@marmooo/midy 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +19 -13
  5. package/esm/midy-GM1.d.ts.map +1 -1
  6. package/esm/midy-GM1.js +171 -131
  7. package/esm/midy-GM2.d.ts +22 -14
  8. package/esm/midy-GM2.d.ts.map +1 -1
  9. package/esm/midy-GM2.js +186 -133
  10. package/esm/midy-GMLite.d.ts +17 -13
  11. package/esm/midy-GMLite.d.ts.map +1 -1
  12. package/esm/midy-GMLite.js +159 -131
  13. package/esm/midy.d.ts +30 -16
  14. package/esm/midy.d.ts.map +1 -1
  15. package/esm/midy.js +266 -166
  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 +19 -13
  21. package/script/midy-GM1.d.ts.map +1 -1
  22. package/script/midy-GM1.js +171 -131
  23. package/script/midy-GM2.d.ts +22 -14
  24. package/script/midy-GM2.d.ts.map +1 -1
  25. package/script/midy-GM2.js +186 -133
  26. package/script/midy-GMLite.d.ts +17 -13
  27. package/script/midy-GMLite.d.ts.map +1 -1
  28. package/script/midy-GMLite.js +159 -131
  29. package/script/midy.d.ts +30 -16
  30. package/script/midy.d.ts.map +1 -1
  31. package/script/midy.js +266 -166
  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.MidyGMLite = 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,31 @@ 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", {
21
27
  enumerable: true,
22
28
  configurable: true,
23
29
  writable: true,
24
30
  value: void 0
25
31
  });
26
- Object.defineProperty(this, "modLFO", {
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, "modLFOGain", {
38
+ Object.defineProperty(this, "modulationDepth", {
33
39
  enumerable: true,
34
40
  configurable: true,
35
41
  writable: true,
@@ -316,7 +322,7 @@ class MidyGMLite {
316
322
  const t = this.audioContext.currentTime + offset;
317
323
  queueIndex = await this.scheduleTimelineEvents(t, offset, queueIndex);
318
324
  if (this.isPausing) {
319
- await this.stopNotes();
325
+ await this.stopNotes(0, true);
320
326
  this.notePromises = [];
321
327
  resolve();
322
328
  this.isPausing = false;
@@ -324,7 +330,7 @@ class MidyGMLite {
324
330
  return;
325
331
  }
326
332
  else if (this.isStopping) {
327
- await this.stopNotes();
333
+ await this.stopNotes(0, true);
328
334
  this.notePromises = [];
329
335
  resolve();
330
336
  this.isStopping = false;
@@ -332,7 +338,7 @@ class MidyGMLite {
332
338
  return;
333
339
  }
334
340
  else if (this.isSeeking) {
335
- this.stopNotes();
341
+ this.stopNotes(0, true);
336
342
  this.startTime = this.audioContext.currentTime;
337
343
  queueIndex = this.getQueueIndex(this.resumeTime);
338
344
  offset = this.resumeTime - this.startTime;
@@ -413,21 +419,25 @@ class MidyGMLite {
413
419
  }
414
420
  return { instruments, timeline };
415
421
  }
416
- stopNotes() {
422
+ async stopChannelNotes(channelNumber, velocity, stopPedal) {
417
423
  const now = this.audioContext.currentTime;
418
- const velocity = 0;
419
- const stopPedal = true;
420
- this.channels.forEach((channel, channelNumber) => {
421
- channel.scheduledNotes.forEach((scheduledNotes) => {
422
- scheduledNotes.forEach((scheduledNote) => {
423
- if (scheduledNote) {
424
- const promise = this.scheduleNoteRelease(channelNumber, scheduledNote.noteNumber, velocity, now, stopPedal);
425
- this.notePromises.push(promise);
426
- }
427
- });
428
- });
429
- channel.scheduledNotes.clear();
424
+ const channel = this.channels[channelNumber];
425
+ channel.scheduledNotes.forEach((noteList) => {
426
+ for (let i = 0; i < noteList.length; i++) {
427
+ const note = noteList[i];
428
+ if (!note)
429
+ continue;
430
+ const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
431
+ this.notePromises.push(promise);
432
+ }
430
433
  });
434
+ channel.scheduledNotes.clear();
435
+ await Promise.all(this.notePromises);
436
+ }
437
+ stopNotes(velocity, stopPedal) {
438
+ for (let i = 0; i < this.channels.length; i++) {
439
+ this.stopChannelNotes(i, velocity, stopPedal);
440
+ }
431
441
  return Promise.all(this.notePromises);
432
442
  }
433
443
  async start() {
@@ -510,75 +520,111 @@ class MidyGMLite {
510
520
  }
511
521
  setVolumeEnvelope(note) {
512
522
  const { instrumentKey, startTime } = note;
513
- note.gainNode = new GainNode(this.audioContext, { gain: 0 });
514
523
  const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
515
524
  const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
516
525
  const volDelay = startTime + instrumentKey.volDelay;
517
526
  const volAttack = volDelay + instrumentKey.volAttack;
518
527
  const volHold = volAttack + instrumentKey.volHold;
519
528
  const volDecay = volHold + instrumentKey.volDecay;
520
- note.gainNode.gain
529
+ note.volumeNode.gain
530
+ .cancelScheduledValues(startTime)
531
+ .setValueAtTime(0, startTime)
521
532
  .setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
522
533
  .exponentialRampToValueAtTime(attackVolume, volAttack)
523
534
  .setValueAtTime(attackVolume, volHold)
524
535
  .linearRampToValueAtTime(sustainVolume, volDecay);
525
536
  }
526
- setFilterEnvelope(channel, note) {
527
- const { instrumentKey, startTime, noteNumber } = note;
528
- const softPedalFactor = 1 -
529
- (0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
530
- const maxFreq = this.audioContext.sampleRate / 2;
531
- const baseFreq = this.centToHz(instrumentKey.initialFilterFc) *
532
- softPedalFactor;
533
- const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
534
- const sustainFreq = (baseFreq +
535
- (peekFreq - baseFreq) * (1 - instrumentKey.modSustain)) * softPedalFactor;
537
+ setPitch(note, semitoneOffset) {
538
+ const { instrumentKey, noteNumber, startTime } = note;
539
+ const modEnvToPitch = instrumentKey.modEnvToPitch / 100;
540
+ note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
541
+ if (modEnvToPitch === 0)
542
+ return;
543
+ const basePitch = note.bufferSource.playbackRate.value;
544
+ const peekPitch = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset + modEnvToPitch);
545
+ const modDelay = startTime + instrumentKey.modDelay;
546
+ const modAttack = modDelay + instrumentKey.modAttack;
547
+ const modHold = modAttack + instrumentKey.modHold;
548
+ const modDecay = modHold + instrumentKey.modDecay;
549
+ note.bufferSource.playbackRate.value
550
+ .setValueAtTime(basePitch, modDelay)
551
+ .exponentialRampToValueAtTime(peekPitch, modAttack)
552
+ .setValueAtTime(peekPitch, modHold)
553
+ .linearRampToValueAtTime(basePitch, modDecay);
554
+ }
555
+ clampCutoffFrequency(frequency) {
556
+ const minFrequency = 20; // min Hz of initialFilterFc
557
+ const maxFrequency = 20000; // max Hz of initialFilterFc
558
+ return Math.max(minFrequency, Math.min(frequency, maxFrequency));
559
+ }
560
+ setFilterEnvelope(note) {
561
+ const { instrumentKey, startTime } = note;
562
+ const baseFreq = this.centToHz(instrumentKey.initialFilterFc);
563
+ const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc);
564
+ const sustainFreq = baseFreq +
565
+ (peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
566
+ const adjustedBaseFreq = this.clampCutoffFrequency(baseFreq);
567
+ const adjustedPeekFreq = this.clampCutoffFrequency(peekFreq);
568
+ const adjustedSustainFreq = this.clampCutoffFrequency(sustainFreq);
536
569
  const modDelay = startTime + instrumentKey.modDelay;
537
570
  const modAttack = modDelay + instrumentKey.modAttack;
538
571
  const modHold = modAttack + instrumentKey.modHold;
539
572
  const modDecay = modHold + instrumentKey.modDecay;
540
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
541
- const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
542
- const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
543
- note.filterNode = new BiquadFilterNode(this.audioContext, {
544
- type: "lowpass",
545
- Q: instrumentKey.initialFilterQ / 10, // dB
546
- frequency: adjustedBaseFreq,
547
- });
548
573
  note.filterNode.frequency
574
+ .cancelScheduledValues(startTime)
575
+ .setValueAtTime(adjustedBaseFreq, startTime)
549
576
  .setValueAtTime(adjustedBaseFreq, modDelay)
550
577
  .exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
551
578
  .setValueAtTime(adjustedPeekFreq, modHold)
552
579
  .linearRampToValueAtTime(adjustedSustainFreq, modDecay);
553
- note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modEnvToPitch, modDelay);
554
580
  }
555
- startModulation(channel, note, time) {
581
+ startModulation(channel, note, startTime) {
556
582
  const { instrumentKey } = note;
557
- note.modLFOGain = new GainNode(this.audioContext, {
558
- gain: this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation),
559
- });
560
- note.modLFO = new OscillatorNode(this.audioContext, {
583
+ const { modLfoToPitch, modLfoToVolume } = instrumentKey;
584
+ note.modulationLFO = new OscillatorNode(this.audioContext, {
561
585
  frequency: this.centToHz(instrumentKey.freqModLFO),
562
586
  });
563
- note.modLFO.start(time);
564
- note.filterNode.frequency.setValueAtTime(note.filterNode.frequency.value + instrumentKey.modLfoToFilterFc, time);
565
- note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modLfoToPitch, time);
566
- note.modLFO.connect(note.modLFOGain);
567
- note.modLFOGain.connect(note.bufferSource.detune);
587
+ note.filterDepth = new GainNode(this.audioContext, {
588
+ gain: instrumentKey.modLfoToFilterFc,
589
+ });
590
+ const modulationDepth = Math.abs(modLfoToPitch) + channel.modulationDepth;
591
+ const modulationDepthSign = (0 < modLfoToPitch) ? 1 : -1;
592
+ note.modulationDepth = new GainNode(this.audioContext, {
593
+ gain: modulationDepth * modulationDepthSign,
594
+ });
595
+ const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
596
+ const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
597
+ note.volumeDepth = new GainNode(this.audioContext, {
598
+ gain: volumeDepth * volumeDepthSign,
599
+ });
600
+ note.modulationLFO.start(startTime + instrumentKey.delayModLFO);
601
+ note.modulationLFO.connect(note.filterDepth);
602
+ note.filterDepth.connect(note.filterNode.frequency);
603
+ note.modulationLFO.connect(note.modulationDepth);
604
+ note.modulationDepth.connect(note.bufferSource.detune);
605
+ note.modulationLFO.connect(note.volumeDepth);
606
+ note.volumeDepth.connect(note.volumeNode.gain);
568
607
  }
569
608
  async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
570
609
  const semitoneOffset = this.calcSemitoneOffset(channel);
571
610
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
572
611
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
573
- note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
612
+ note.volumeNode = new GainNode(this.audioContext);
613
+ note.filterNode = new BiquadFilterNode(this.audioContext, {
614
+ type: "lowpass",
615
+ Q: instrumentKey.initialFilterQ / 10 * channel.filterResonance, // dB
616
+ });
574
617
  this.setVolumeEnvelope(note);
575
- this.setFilterEnvelope(channel, note);
576
- if (channel.modulation > 0) {
577
- const delayModLFO = startTime + instrumentKey.delayModLFO;
578
- this.startModulation(channel, note, delayModLFO);
618
+ this.setFilterEnvelope(note);
619
+ if (0 < channel.modulationDepth) {
620
+ this.setPitch(note, semitoneOffset);
621
+ this.startModulation(channel, note, startTime);
622
+ }
623
+ else {
624
+ note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
579
625
  }
580
626
  note.bufferSource.connect(note.filterNode);
581
- note.filterNode.connect(note.gainNode);
627
+ note.filterNode.connect(note.volumeNode);
582
628
  note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
583
629
  return note;
584
630
  }
@@ -594,8 +640,8 @@ class MidyGMLite {
594
640
  if (!instrumentKey)
595
641
  return;
596
642
  const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
597
- note.gainNode.connect(channel.gainL);
598
- note.gainNode.connect(channel.gainR);
643
+ note.volumeNode.connect(channel.gainL);
644
+ note.volumeNode.connect(channel.gainR);
599
645
  const scheduledNotes = channel.scheduledNotes;
600
646
  if (scheduledNotes.has(noteNumber)) {
601
647
  scheduledNotes.get(noteNumber).push(note);
@@ -608,7 +654,7 @@ class MidyGMLite {
608
654
  const now = this.audioContext.currentTime;
609
655
  return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
610
656
  }
611
- scheduleNoteRelease(channelNumber, noteNumber, velocity, stopTime, stopPedal = false) {
657
+ scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, stopPedal = false) {
612
658
  const channel = this.channels[channelNumber];
613
659
  if (stopPedal && channel.sustainPedal)
614
660
  return;
@@ -621,20 +667,14 @@ class MidyGMLite {
621
667
  continue;
622
668
  if (note.ending)
623
669
  continue;
624
- const velocityRate = (velocity + 127) / 127;
625
- const volEndTime = stopTime +
626
- note.instrumentKey.volRelease * velocityRate;
627
- note.gainNode.gain
670
+ const volEndTime = stopTime + note.instrumentKey.volRelease;
671
+ note.volumeNode.gain
628
672
  .cancelScheduledValues(stopTime)
629
673
  .linearRampToValueAtTime(0, volEndTime);
630
- const maxFreq = this.audioContext.sampleRate / 2;
631
- const baseFreq = this.centToHz(note.instrumentKey.initialFilterFc);
632
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
633
- const modEndTime = stopTime +
634
- note.instrumentKey.modRelease * velocityRate;
674
+ const modRelease = stopTime + note.instrumentKey.modRelease;
635
675
  note.filterNode.frequency
636
676
  .cancelScheduledValues(stopTime)
637
- .linearRampToValueAtTime(adjustedBaseFreq, modEndTime);
677
+ .linearRampToValueAtTime(0, modRelease);
638
678
  note.ending = true;
639
679
  this.scheduleTask(() => {
640
680
  note.bufferSource.loop = false;
@@ -643,15 +683,17 @@ class MidyGMLite {
643
683
  note.bufferSource.onended = () => {
644
684
  scheduledNotes[i] = null;
645
685
  note.bufferSource.disconnect();
686
+ note.volumeNode.disconnect();
646
687
  note.filterNode.disconnect();
647
- note.gainNode.disconnect();
648
- if (note.modLFOGain)
649
- note.modLFOGain.disconnect();
650
- if (note.modLFO)
651
- note.modLFO.stop();
688
+ if (note.volumeDepth)
689
+ note.volumeDepth.disconnect();
690
+ if (note.modulationDepth)
691
+ note.modulationDepth.disconnect();
692
+ if (note.modulationLFO)
693
+ note.modulationLFO.stop();
652
694
  resolve();
653
695
  };
654
- bufferSource.stop(volEndTime);
696
+ note.bufferSource.stop(volEndTime);
655
697
  });
656
698
  }
657
699
  }
@@ -664,14 +706,15 @@ class MidyGMLite {
664
706
  const channel = this.channels[channelNumber];
665
707
  const promises = [];
666
708
  channel.sustainPedal = false;
667
- channel.scheduledNotes.forEach((scheduledNotes) => {
668
- scheduledNotes.forEach((scheduledNote) => {
669
- if (scheduledNote) {
670
- const { noteNumber } = scheduledNote;
671
- const promise = this.releaseNote(channelNumber, noteNumber, velocity);
672
- promises.push(promise);
673
- }
674
- });
709
+ channel.scheduledNotes.forEach((noteList) => {
710
+ for (let i = 0; i < noteList.length; i++) {
711
+ const note = noteList[i];
712
+ if (!note)
713
+ continue;
714
+ const { noteNumber } = note;
715
+ const promise = this.releaseNote(channelNumber, noteNumber, velocity);
716
+ promises.push(promise);
717
+ }
675
718
  });
676
719
  return promises;
677
720
  }
@@ -712,7 +755,7 @@ class MidyGMLite {
712
755
  handleControlChange(channelNumber, controller, value) {
713
756
  switch (controller) {
714
757
  case 1:
715
- return this.setModulation(channelNumber, value);
758
+ return this.setModulationDepth(channelNumber, value);
716
759
  case 6:
717
760
  return this.dataEntryMSB(channelNumber, value);
718
761
  case 7:
@@ -741,20 +784,25 @@ class MidyGMLite {
741
784
  }
742
785
  updateModulation(channel) {
743
786
  const now = this.audioContext.currentTime;
744
- const activeNotes = this.getActiveNotes(channel, now);
745
- activeNotes.forEach((activeNote) => {
746
- if (activeNote.modLFO) {
747
- const { gainNode, instrumentKey } = activeNote;
748
- gainNode.gain.setValueAtTime(this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation), now);
749
- }
750
- else {
751
- this.startModulation(channel, activeNote, now);
787
+ channel.scheduledNotes.forEach((noteList) => {
788
+ for (let i = 0; i < noteList.length; i++) {
789
+ const note = noteList[i];
790
+ if (!note)
791
+ continue;
792
+ if (note.modulationDepth) {
793
+ note.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
794
+ }
795
+ else {
796
+ const semitoneOffset = this.calcSemitoneOffset(channel);
797
+ this.setPitch(note, semitoneOffset);
798
+ this.startModulation(channel, note, now);
799
+ }
752
800
  }
753
801
  });
754
802
  }
755
- setModulation(channelNumber, modulation) {
803
+ setModulationDepth(channelNumber, modulation) {
756
804
  const channel = this.channels[channelNumber];
757
- channel.modulation = (modulation / 127) * channel.modulationDepthRange;
805
+ channel.modulationDepth = (modulation / 127) * channel.modulationDepthRange;
758
806
  this.updateModulation(channel);
759
807
  }
760
808
  setVolume(channelNumber, volume) {
@@ -824,13 +872,17 @@ class MidyGMLite {
824
872
  }
825
873
  updateDetune(channel, detuneChange) {
826
874
  const now = this.audioContext.currentTime;
827
- const activeNotes = this.getActiveNotes(channel, now);
828
- activeNotes.forEach((activeNote) => {
829
- const { bufferSource } = activeNote;
830
- const detune = bufferSource.detune.value + detuneChange;
831
- bufferSource.detune
832
- .cancelScheduledValues(now)
833
- .setValueAtTime(detune, now);
875
+ channel.scheduledNotes.forEach((noteList) => {
876
+ for (let i = 0; i < noteList.length; i++) {
877
+ const note = noteList[i];
878
+ if (!note)
879
+ continue;
880
+ const { bufferSource } = note;
881
+ const detune = bufferSource.detune.value + detuneChange;
882
+ bufferSource.detune
883
+ .cancelScheduledValues(now)
884
+ .setValueAtTime(detune, now);
885
+ }
834
886
  });
835
887
  }
836
888
  handlePitchBendRangeRPN(channelNumber) {
@@ -848,37 +900,13 @@ class MidyGMLite {
848
900
  this.updateDetune(channel, detuneChange);
849
901
  }
850
902
  allSoundOff(channelNumber) {
851
- const now = this.audioContext.currentTime;
852
- const channel = this.channels[channelNumber];
853
- const velocity = 0;
854
- const stopPedal = true;
855
- const promises = [];
856
- channel.scheduledNotes.forEach((noteList) => {
857
- const activeNote = this.getActiveNote(noteList, now);
858
- if (activeNote) {
859
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
860
- promises.push(notePromise);
861
- }
862
- });
863
- return promises;
903
+ return this.stopChannelNotes(channelNumber, 0, true);
864
904
  }
865
905
  resetAllControllers(channelNumber) {
866
906
  Object.assign(this.channels[channelNumber], this.effectSettings);
867
907
  }
868
908
  allNotesOff(channelNumber) {
869
- const now = this.audioContext.currentTime;
870
- const channel = this.channels[channelNumber];
871
- const velocity = 0;
872
- const stopPedal = false;
873
- const promises = [];
874
- channel.scheduledNotes.forEach((noteList) => {
875
- const activeNote = this.getActiveNote(noteList, now);
876
- if (activeNote) {
877
- const notePromise = this.scheduleNoteRelease(channelNumber, activeNote.noteNumber, velocity, now, stopPedal);
878
- promises.push(notePromise);
879
- }
880
- });
881
- return promises;
909
+ return this.stopChannelNotes(channelNumber, 0, false);
882
910
  }
883
911
  handleUniversalNonRealTimeExclusiveMessage(data) {
884
912
  switch (data[2]) {
@@ -972,7 +1000,7 @@ Object.defineProperty(MidyGMLite, "channelSettings", {
972
1000
  dataLSB: 0,
973
1001
  program: 0,
974
1002
  pitchBend: 0,
975
- modulationDepthRange: 0.5, // cb
1003
+ modulationDepthRange: 50, // cent
976
1004
  }
977
1005
  });
978
1006
  Object.defineProperty(MidyGMLite, "effectSettings", {
@@ -981,7 +1009,7 @@ Object.defineProperty(MidyGMLite, "effectSettings", {
981
1009
  writable: true,
982
1010
  value: {
983
1011
  expression: 1,
984
- modulation: 0,
1012
+ modulationDepth: 0,
985
1013
  sustainPedal: false,
986
1014
  rpnMSB: 127,
987
1015
  rpnLSB: 127,
package/script/midy.d.ts CHANGED
@@ -4,6 +4,11 @@ export class Midy {
4
4
  volume: number;
5
5
  pan: number;
6
6
  portamentoTime: number;
7
+ filterResonance: number;
8
+ releaseTime: number;
9
+ attackTime: number;
10
+ brightness: number;
11
+ decayTime: number;
7
12
  reverbSendLevel: number;
8
13
  chorusSendLevel: number;
9
14
  vibratoRate: number;
@@ -22,7 +27,7 @@ export class Midy {
22
27
  };
23
28
  static effectSettings: {
24
29
  expression: number;
25
- modulation: number;
30
+ modulationDepth: number;
26
31
  sustainPedal: boolean;
27
32
  portamento: boolean;
28
33
  sostenutoPedal: boolean;
@@ -128,7 +133,8 @@ export class Midy {
128
133
  instruments: Set<any>;
129
134
  timeline: any[];
130
135
  };
131
- stopNotes(): Promise<any[]>;
136
+ stopChannelNotes(channelNumber: any, velocity: any, stopPedal: any): Promise<void>;
137
+ stopNotes(velocity: any, stopPedal: any): Promise<any[]>;
132
138
  start(): Promise<void>;
133
139
  stop(): void;
134
140
  pause(): void;
@@ -164,28 +170,30 @@ export class Midy {
164
170
  centToHz(cent: any): number;
165
171
  calcSemitoneOffset(channel: any): any;
166
172
  calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
167
- setVolumeEnvelope(note: any): void;
173
+ setVolumeEnvelope(channel: any, note: any): void;
174
+ setPitch(note: any, semitoneOffset: any): void;
175
+ clampCutoffFrequency(frequency: any): number;
168
176
  setFilterEnvelope(channel: any, note: any): void;
169
- startModulation(channel: any, note: any, time: any): void;
170
- startVibrato(channel: any, note: any, time: any): void;
177
+ startModulation(channel: any, note: any, startTime: any): void;
178
+ startVibrato(channel: any, note: any, startTime: any): void;
171
179
  createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
172
180
  calcBank(channel: any, channelNumber: any): any;
173
181
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
174
182
  noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
175
- scheduleNoteRelease(channelNumber: any, noteNumber: any, velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
183
+ scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
176
184
  releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
177
185
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
178
186
  releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
179
- handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
187
+ handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
180
188
  handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
181
189
  handleProgramChange(channelNumber: any, program: any): void;
182
190
  handleChannelPressure(channelNumber: any, pressure: any): void;
183
191
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
184
192
  setPitchBend(channelNumber: any, pitchBend: any): void;
185
- handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
193
+ handleControlChange(channelNumber: any, controller: any, value: any): void | Promise<void>;
186
194
  setBankMSB(channelNumber: any, msb: any): void;
187
195
  updateModulation(channel: any): void;
188
- setModulation(channelNumber: any, modulation: any): void;
196
+ setModulationDepth(channelNumber: any, modulation: any): void;
189
197
  setPortamentoTime(channelNumber: any, portamentoTime: any): void;
190
198
  setVolume(channelNumber: any, volume: any): void;
191
199
  panToGain(pan: any): {
@@ -203,6 +211,11 @@ export class Midy {
203
211
  setChorusSendLevel(channelNumber: any, chorusSendLevel: any): void;
204
212
  setSostenutoPedal(channelNumber: any, value: any): void;
205
213
  setSoftPedal(channelNumber: any, softPedal: any): void;
214
+ setFilterResonance(channelNumber: any, filterResonance: any): void;
215
+ setReleaseTime(channelNumber: any, releaseTime: any): void;
216
+ setAttackTime(channelNumber: any, attackTime: any): void;
217
+ setBrightness(channelNumber: any, brightness: any): void;
218
+ setDecayTime(channelNumber: any, dacayTime: any): void;
206
219
  setVibratoRate(channelNumber: any, vibratoRate: any): void;
207
220
  setVibratoDepth(channelNumber: any, vibratoDepth: any): void;
208
221
  setVibratoDelay(channelNumber: any, vibratoDelay: any): void;
@@ -223,9 +236,9 @@ export class Midy {
223
236
  setCoarseTuning(channelNumber: any, coarseTuning: any): void;
224
237
  handleModulationDepthRangeRPN(channelNumber: any): void;
225
238
  setModulationDepthRange(channelNumber: any, modulationDepthRange: any): void;
226
- allSoundOff(channelNumber: any): any[];
239
+ allSoundOff(channelNumber: any): Promise<void>;
227
240
  resetAllControllers(channelNumber: any): void;
228
- allNotesOff(channelNumber: any): any[];
241
+ allNotesOff(channelNumber: any): Promise<void>;
229
242
  omniOff(): void;
230
243
  omniOn(): void;
231
244
  monoOn(): void;
@@ -265,12 +278,13 @@ export class Midy {
265
278
  declare class Note {
266
279
  constructor(noteNumber: any, velocity: any, startTime: any, instrumentKey: any);
267
280
  bufferSource: any;
268
- gainNode: any;
269
281
  filterNode: any;
270
- modLFO: any;
271
- modLFOGain: any;
272
- vibLFO: any;
273
- vibLFOGain: any;
282
+ volumeNode: any;
283
+ volumeDepth: any;
284
+ modulationLFO: any;
285
+ modulationDepth: any;
286
+ vibratoLFO: any;
287
+ vibratoDepth: any;
274
288
  noteNumber: any;
275
289
  velocity: any;
276
290
  startTime: any;
@@ -1 +1 @@
1
- {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}