@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
package/esm/midy-GM1.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,25 +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", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: void 0
28
+ });
29
+ Object.defineProperty(this, "modulationLFO", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: void 0
34
+ });
35
+ Object.defineProperty(this, "modulationDepth", {
18
36
  enumerable: true,
19
37
  configurable: true,
20
38
  writable: true,
21
39
  value: void 0
22
40
  });
23
- Object.defineProperty(this, "modLFO", {
41
+ Object.defineProperty(this, "vibratoLFO", {
24
42
  enumerable: true,
25
43
  configurable: true,
26
44
  writable: true,
27
45
  value: void 0
28
46
  });
29
- Object.defineProperty(this, "modLFOGain", {
47
+ Object.defineProperty(this, "vibratoDepth", {
30
48
  enumerable: true,
31
49
  configurable: true,
32
50
  writable: true,
@@ -144,8 +162,8 @@ export class MidyGM1 {
144
162
  });
145
163
  this.audioContext = audioContext;
146
164
  this.masterGain = new GainNode(audioContext);
147
- this.masterGain.connect(audioContext.destination);
148
165
  this.channels = this.createChannels(audioContext);
166
+ this.masterGain.connect(audioContext.destination);
149
167
  this.GM1SystemOn();
150
168
  }
151
169
  initSoundFontTable() {
@@ -189,6 +207,7 @@ export class MidyGM1 {
189
207
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
190
208
  gainL.connect(merger, 0, 0);
191
209
  gainR.connect(merger, 0, 1);
210
+ merger.connect(this.masterGain);
192
211
  return {
193
212
  gainL,
194
213
  gainR,
@@ -312,7 +331,7 @@ export class MidyGM1 {
312
331
  const t = this.audioContext.currentTime + offset;
313
332
  queueIndex = await this.scheduleTimelineEvents(t, offset, queueIndex);
314
333
  if (this.isPausing) {
315
- await this.stopNotes();
334
+ await this.stopNotes(0, true);
316
335
  this.notePromises = [];
317
336
  resolve();
318
337
  this.isPausing = false;
@@ -320,7 +339,7 @@ export class MidyGM1 {
320
339
  return;
321
340
  }
322
341
  else if (this.isStopping) {
323
- await this.stopNotes();
342
+ await this.stopNotes(0, true);
324
343
  this.notePromises = [];
325
344
  resolve();
326
345
  this.isStopping = false;
@@ -328,7 +347,7 @@ export class MidyGM1 {
328
347
  return;
329
348
  }
330
349
  else if (this.isSeeking) {
331
- this.stopNotes();
350
+ this.stopNotes(0, true);
332
351
  this.startTime = this.audioContext.currentTime;
333
352
  queueIndex = this.getQueueIndex(this.resumeTime);
334
353
  offset = this.resumeTime - this.startTime;
@@ -409,21 +428,24 @@ export class MidyGM1 {
409
428
  }
410
429
  return { instruments, timeline };
411
430
  }
412
- stopNotes() {
431
+ async stopChannelNotes(channelNumber, velocity, stopPedal) {
413
432
  const now = this.audioContext.currentTime;
414
- const velocity = 0;
415
- const stopPedal = true;
416
- this.channels.forEach((channel, channelNumber) => {
417
- channel.scheduledNotes.forEach((scheduledNotes) => {
418
- scheduledNotes.forEach((scheduledNote) => {
419
- if (scheduledNote) {
420
- const promise = this.scheduleNoteRelease(channelNumber, scheduledNote.noteNumber, velocity, now, stopPedal);
421
- this.notePromises.push(promise);
422
- }
423
- });
433
+ const channel = this.channels[channelNumber];
434
+ channel.scheduledNotes.forEach((noteList) => {
435
+ noteList.forEach((note) => {
436
+ if (note) {
437
+ const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
438
+ this.notePromises.push(promise);
439
+ }
424
440
  });
425
- channel.scheduledNotes.clear();
426
441
  });
442
+ channel.scheduledNotes.clear();
443
+ await Promise.all(this.notePromises);
444
+ }
445
+ stopNotes(velocity, stopPedal) {
446
+ for (let i = 0; i < this.channels.length; i++) {
447
+ this.stopChannelNotes(i, velocity, stopPedal);
448
+ }
427
449
  return Promise.all(this.notePromises);
428
450
  }
429
451
  async start() {
@@ -491,10 +513,6 @@ export class MidyGM1 {
491
513
  }
492
514
  return noteList[0];
493
515
  }
494
- connectEffects(channel, gainNode) {
495
- gainNode.connect(channel.merger);
496
- merger.connect(this.masterGain);
497
- }
498
516
  cbToRatio(cb) {
499
517
  return Math.pow(10, cb / 200);
500
518
  }
@@ -509,27 +527,41 @@ export class MidyGM1 {
509
527
  return instrumentKey.playbackRate(noteNumber) *
510
528
  Math.pow(2, semitoneOffset / 12);
511
529
  }
512
- setVolumeEnvelope(channel, note) {
513
- const { instrumentKey, startTime, velocity } = note;
514
- note.gainNode = new GainNode(this.audioContext, { gain: 0 });
515
- let volume = (velocity / 127) * channel.volume * channel.expression;
516
- if (volume === 0)
517
- volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
518
- const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation) *
519
- volume;
530
+ setVolumeEnvelope(note) {
531
+ const { instrumentKey, startTime } = note;
532
+ note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
533
+ const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
520
534
  const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
521
535
  const volDelay = startTime + instrumentKey.volDelay;
522
536
  const volAttack = volDelay + instrumentKey.volAttack;
523
537
  const volHold = volAttack + instrumentKey.volHold;
524
538
  const volDecay = volHold + instrumentKey.volDecay;
525
- note.gainNode.gain
539
+ note.volumeNode.gain
526
540
  .setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
527
541
  .exponentialRampToValueAtTime(attackVolume, volAttack)
528
542
  .setValueAtTime(attackVolume, volHold)
529
543
  .linearRampToValueAtTime(sustainVolume, volDecay);
530
544
  }
531
- setFilterEnvelope(channel, note) {
532
- const { instrumentKey, startTime, noteNumber } = note;
545
+ setPitch(note, semitoneOffset) {
546
+ const { instrumentKey, noteNumber, startTime } = note;
547
+ const modEnvToPitch = instrumentKey.modEnvToPitch / 100;
548
+ note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
549
+ if (modEnvToPitch === 0)
550
+ return;
551
+ const basePitch = note.bufferSource.playbackRate.value;
552
+ const peekPitch = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset + modEnvToPitch);
553
+ const modDelay = startTime + instrumentKey.modDelay;
554
+ const modAttack = modDelay + instrumentKey.modAttack;
555
+ const modHold = modAttack + instrumentKey.modHold;
556
+ const modDecay = modHold + instrumentKey.modDecay;
557
+ note.bufferSource.playbackRate.value
558
+ .setValueAtTime(basePitch, modDelay)
559
+ .exponentialRampToValueAtTime(peekPitch, modAttack)
560
+ .setValueAtTime(peekPitch, modHold)
561
+ .linearRampToValueAtTime(basePitch, modDecay);
562
+ }
563
+ setFilterNode(channel, note) {
564
+ const { instrumentKey, noteNumber, startTime } = note;
533
565
  const softPedalFactor = 1 -
534
566
  (0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
535
567
  const maxFreq = this.audioContext.sampleRate / 2;
@@ -538,13 +570,13 @@ export class MidyGM1 {
538
570
  const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
539
571
  const sustainFreq = (baseFreq +
540
572
  (peekFreq - baseFreq) * (1 - instrumentKey.modSustain)) * softPedalFactor;
573
+ const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
574
+ const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
575
+ const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
541
576
  const modDelay = startTime + instrumentKey.modDelay;
542
577
  const modAttack = modDelay + instrumentKey.modAttack;
543
578
  const modHold = modAttack + instrumentKey.modHold;
544
579
  const modDecay = modHold + instrumentKey.modDecay;
545
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
546
- const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
547
- const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
548
580
  note.filterNode = new BiquadFilterNode(this.audioContext, {
549
581
  type: "lowpass",
550
582
  Q: instrumentKey.initialFilterQ / 10, // dB
@@ -555,35 +587,49 @@ export class MidyGM1 {
555
587
  .exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
556
588
  .setValueAtTime(adjustedPeekFreq, modHold)
557
589
  .linearRampToValueAtTime(adjustedSustainFreq, modDecay);
558
- note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modEnvToPitch, modDelay);
559
590
  }
560
- startModulation(channel, note, time) {
591
+ startModulation(channel, note, startTime) {
561
592
  const { instrumentKey } = note;
562
- note.modLFOGain = new GainNode(this.audioContext, {
563
- gain: this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation),
564
- });
565
- note.modLFO = new OscillatorNode(this.audioContext, {
593
+ const { modLfoToPitch, modLfoToVolume } = instrumentKey;
594
+ note.modulationLFO = new OscillatorNode(this.audioContext, {
566
595
  frequency: this.centToHz(instrumentKey.freqModLFO),
567
596
  });
568
- note.modLFO.start(time);
569
- note.filterNode.frequency.setValueAtTime(note.filterNode.frequency.value + instrumentKey.modLfoToFilterFc, time);
570
- note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modLfoToPitch, time);
571
- note.modLFO.connect(note.modLFOGain);
572
- note.modLFOGain.connect(note.bufferSource.detune);
597
+ note.filterDepth = new GainNode(this.audioContext, {
598
+ gain: instrumentKey.modLfoToFilterFc,
599
+ });
600
+ const modulationDepth = Math.abs(modLfoToPitch) + channel.modulationDepth;
601
+ const modulationDepthSign = (0 < modLfoToPitch) ? 1 : -1;
602
+ note.modulationDepth = new GainNode(this.audioContext, {
603
+ gain: modulationDepth * modulationDepthSign,
604
+ });
605
+ const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
606
+ const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
607
+ note.volumeDepth = new GainNode(this.audioContext, {
608
+ gain: volumeDepth * volumeDepthSign,
609
+ });
610
+ note.modulationLFO.start(startTime + instrumentKey.delayModLFO);
611
+ note.modulationLFO.connect(note.filterDepth);
612
+ note.filterDepth.connect(note.filterNode.frequency);
613
+ note.modulationLFO.connect(note.modulationDepth);
614
+ note.modulationDepth.connect(note.bufferSource.detune);
615
+ note.modulationLFO.connect(note.volumeDepth);
616
+ note.volumeDepth.connect(note.volumeNode.gain);
573
617
  }
574
618
  async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
575
619
  const semitoneOffset = this.calcSemitoneOffset(channel);
576
620
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
577
621
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
578
- note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
579
- this.setVolumeEnvelope(channel, note);
580
- this.setFilterEnvelope(channel, note);
581
- if (channel.modulation > 0) {
582
- const delayModLFO = startTime + instrumentKey.delayModLFO;
583
- this.startModulation(channel, note, delayModLFO);
622
+ this.setFilterNode(channel, note);
623
+ this.setVolumeEnvelope(note);
624
+ if (0 < channel.modulationDepth) {
625
+ this.setPitch(note, semitoneOffset);
626
+ this.startModulation(channel, note, startTime);
627
+ }
628
+ else {
629
+ note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
584
630
  }
585
631
  note.bufferSource.connect(note.filterNode);
586
- note.filterNode.connect(note.gainNode);
632
+ note.filterNode.connect(note.volumeNode);
587
633
  note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
588
634
  return note;
589
635
  }
@@ -599,7 +645,8 @@ export class MidyGM1 {
599
645
  if (!instrumentKey)
600
646
  return;
601
647
  const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
602
- this.connectEffects(channel, note.gainNode);
648
+ note.volumeNode.connect(channel.gainL);
649
+ note.volumeNode.connect(channel.gainR);
603
650
  const scheduledNotes = channel.scheduledNotes;
604
651
  if (scheduledNotes.has(noteNumber)) {
605
652
  scheduledNotes.get(noteNumber).push(note);
@@ -628,17 +675,14 @@ export class MidyGM1 {
628
675
  const velocityRate = (velocity + 127) / 127;
629
676
  const volEndTime = stopTime +
630
677
  note.instrumentKey.volRelease * velocityRate;
631
- note.gainNode.gain
678
+ note.volumeNode.gain
632
679
  .cancelScheduledValues(stopTime)
633
680
  .linearRampToValueAtTime(0, volEndTime);
634
- const maxFreq = this.audioContext.sampleRate / 2;
635
- const baseFreq = this.centToHz(note.instrumentKey.initialFilterFc);
636
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
637
- const modEndTime = stopTime +
681
+ const modRelease = stopTime +
638
682
  note.instrumentKey.modRelease * velocityRate;
639
683
  note.filterNode.frequency
640
684
  .cancelScheduledValues(stopTime)
641
- .linearRampToValueAtTime(adjustedBaseFreq, modEndTime);
685
+ .linearRampToValueAtTime(0, modRelease);
642
686
  note.ending = true;
643
687
  this.scheduleTask(() => {
644
688
  note.bufferSource.loop = false;
@@ -647,15 +691,17 @@ export class MidyGM1 {
647
691
  note.bufferSource.onended = () => {
648
692
  scheduledNotes[i] = null;
649
693
  note.bufferSource.disconnect();
694
+ note.volumeNode.disconnect();
650
695
  note.filterNode.disconnect();
651
- note.gainNode.disconnect();
652
- if (note.modLFOGain)
653
- note.modLFOGain.disconnect();
654
- if (note.modLFO)
655
- note.modLFO.stop();
696
+ if (note.volumeDepth)
697
+ note.volumeDepth.disconnect();
698
+ if (note.modulationDepth)
699
+ note.modulationDepth.disconnect();
700
+ if (note.modulationLFO)
701
+ note.modulationLFO.stop();
656
702
  resolve();
657
703
  };
658
- bufferSource.stop(volEndTime);
704
+ note.bufferSource.stop(volEndTime);
659
705
  });
660
706
  }
661
707
  }
@@ -668,10 +714,10 @@ export class MidyGM1 {
668
714
  const channel = this.channels[channelNumber];
669
715
  const promises = [];
670
716
  channel.sustainPedal = false;
671
- channel.scheduledNotes.forEach((scheduledNotes) => {
672
- scheduledNotes.forEach((scheduledNote) => {
673
- if (scheduledNote) {
674
- const { noteNumber } = scheduledNote;
717
+ channel.scheduledNotes.forEach((noteList) => {
718
+ noteList.forEach((note) => {
719
+ if (note) {
720
+ const { noteNumber } = note;
675
721
  const promise = this.releaseNote(channelNumber, noteNumber, velocity);
676
722
  promises.push(promise);
677
723
  }
@@ -702,13 +748,13 @@ export class MidyGM1 {
702
748
  channel.program = program;
703
749
  }
704
750
  handlePitchBendMessage(channelNumber, lsb, msb) {
705
- const pitchBend = msb * 128 + lsb;
751
+ const pitchBend = msb * 128 + lsb - 8192;
706
752
  this.setPitchBend(channelNumber, pitchBend);
707
753
  }
708
754
  setPitchBend(channelNumber, pitchBend) {
709
755
  const channel = this.channels[channelNumber];
710
756
  const prevPitchBend = channel.pitchBend;
711
- channel.pitchBend = (pitchBend - 8192) / 8192;
757
+ channel.pitchBend = pitchBend / 8192;
712
758
  const detuneChange = (channel.pitchBend - prevPitchBend) *
713
759
  channel.pitchBendRange * 100;
714
760
  this.updateDetune(channel, detuneChange);
@@ -716,7 +762,7 @@ export class MidyGM1 {
716
762
  handleControlChange(channelNumber, controller, value) {
717
763
  switch (controller) {
718
764
  case 1:
719
- return this.setModulation(channelNumber, value);
765
+ return this.setModulationDepth(channelNumber, value);
720
766
  case 6:
721
767
  return this.dataEntryMSB(channelNumber, value);
722
768
  case 7:
@@ -747,18 +793,19 @@ export class MidyGM1 {
747
793
  const now = this.audioContext.currentTime;
748
794
  const activeNotes = this.getActiveNotes(channel, now);
749
795
  activeNotes.forEach((activeNote) => {
750
- if (activeNote.modLFO) {
751
- const { gainNode, instrumentKey } = activeNote;
752
- gainNode.gain.setValueAtTime(this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation), now);
796
+ if (activeNote.modulationDepth) {
797
+ activeNote.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
753
798
  }
754
799
  else {
800
+ const semitoneOffset = this.calcSemitoneOffset(channel);
801
+ this.setPitch(activeNote, semitoneOffset);
755
802
  this.startModulation(channel, activeNote, now);
756
803
  }
757
804
  });
758
805
  }
759
- setModulation(channelNumber, modulation) {
806
+ setModulationDepth(channelNumber, modulation) {
760
807
  const channel = this.channels[channelNumber];
761
- channel.modulation = (modulation / 127) * channel.modulationDepthRange;
808
+ channel.modulationDepth = (modulation / 127) * channel.modulationDepthRange;
762
809
  this.updateModulation(channel);
763
810
  }
764
811
  setVolume(channelNumber, volume) {
@@ -910,37 +957,13 @@ export class MidyGM1 {
910
957
  this.updateDetune(channel, detuneChange);
911
958
  }
912
959
  allSoundOff(channelNumber) {
913
- const now = this.audioContext.currentTime;
914
- const channel = this.channels[channelNumber];
915
- const velocity = 0;
916
- const stopPedal = true;
917
- const promises = [];
918
- channel.scheduledNotes.forEach((noteList) => {
919
- const activeNote = this.getActiveNote(noteList, now);
920
- if (activeNote) {
921
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
922
- promises.push(notePromise);
923
- }
924
- });
925
- return promises;
960
+ return this.stopChannelNotes(channelNumber, 0, true);
926
961
  }
927
962
  resetAllControllers(channelNumber) {
928
963
  Object.assign(this.channels[channelNumber], this.effectSettings);
929
964
  }
930
965
  allNotesOff(channelNumber) {
931
- const now = this.audioContext.currentTime;
932
- const channel = this.channels[channelNumber];
933
- const velocity = 0;
934
- const stopPedal = false;
935
- const promises = [];
936
- channel.scheduledNotes.forEach((noteList) => {
937
- const activeNote = this.getActiveNote(noteList, now);
938
- if (activeNote) {
939
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
940
- promises.push(notePromise);
941
- }
942
- });
943
- return promises;
966
+ return this.stopChannelNotes(channelNumber, 0, false);
944
967
  }
945
968
  handleUniversalNonRealTimeExclusiveMessage(data) {
946
969
  switch (data[2]) {
@@ -1035,7 +1058,7 @@ Object.defineProperty(MidyGM1, "channelSettings", {
1035
1058
  pitchBend: 0,
1036
1059
  fineTuning: 0, // cb
1037
1060
  coarseTuning: 0, // cb
1038
- modulationDepthRange: 0.5, // cb
1061
+ modulationDepthRange: 50, // cent
1039
1062
  }
1040
1063
  });
1041
1064
  Object.defineProperty(MidyGM1, "effectSettings", {
@@ -1044,7 +1067,7 @@ Object.defineProperty(MidyGM1, "effectSettings", {
1044
1067
  writable: true,
1045
1068
  value: {
1046
1069
  expression: 1,
1047
- modulation: 0,
1070
+ modulationDepth: 0,
1048
1071
  sustainPedal: false,
1049
1072
  rpnMSB: 127,
1050
1073
  rpnLSB: 127,
package/esm/midy-GM2.d.ts CHANGED
@@ -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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"}