@marmooo/midy 0.4.1 → 0.4.2

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.
@@ -1,4 +1,4 @@
1
- export class MidyGM1 {
1
+ export class MidyGM1 extends EventTarget {
2
2
  static channelSettings: {
3
3
  scheduleIndex: number;
4
4
  detune: number;
@@ -31,6 +31,7 @@ export class MidyGM1 {
31
31
  isPaused: boolean;
32
32
  isStopping: boolean;
33
33
  isSeeking: boolean;
34
+ loop: boolean;
34
35
  playPromise: any;
35
36
  timeline: any[];
36
37
  notePromises: any[];
@@ -69,7 +70,7 @@ export class MidyGM1 {
69
70
  createChannels(audioContext: any): any[];
70
71
  createAudioBuffer(voiceParams: any): Promise<any>;
71
72
  createBufferSource(voiceParams: any, audioBuffer: any): any;
72
- scheduleTimelineEvents(scheduleTime: any, queueIndex: any): Promise<any>;
73
+ scheduleTimelineEvents(scheduleTime: any, queueIndex: any): any;
73
74
  getQueueIndex(second: any): number;
74
75
  resetAllStates(): void;
75
76
  updateStates(queueIndex: any, nextQueueIndex: any): void;
@@ -91,8 +92,8 @@ export class MidyGM1 {
91
92
  seekTo(second: any): void;
92
93
  calcTotalTime(): number;
93
94
  currentTime(): number;
94
- processScheduledNotes(channel: any, callback: any): void;
95
- processActiveNotes(channel: any, scheduleTime: any, callback: any): void;
95
+ processScheduledNotes(channel: any, callback: any): Promise<void>;
96
+ processActiveNotes(channel: any, scheduleTime: any, callback: any): Promise<void>;
96
97
  cbToRatio(cb: any): number;
97
98
  rateToCent(rate: any): number;
98
99
  centToRate(cent: any): number;
@@ -112,13 +113,13 @@ export class MidyGM1 {
112
113
  noteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
113
114
  disconnectNote(note: any): void;
114
115
  releaseNote(channel: any, note: any, endTime: any): Promise<any>;
115
- noteOff(channelNumber: any, noteNumber: any, velocity: any, endTime: any, force: any): Promise<any> | undefined;
116
+ noteOff(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, force: any): any;
116
117
  setNoteIndex(channel: any, index: any): void;
117
118
  findNoteOffIndex(channel: any, noteNumber: any): any;
118
- releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
119
+ releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): any[];
119
120
  createMessageHandlers(): any[];
120
121
  handleMessage(data: any, scheduleTime: any): void;
121
- handleChannelMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<any>;
122
+ handleChannelMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): any;
122
123
  setProgramChange(channelNumber: any, programNumber: any, _scheduleTime: any): void;
123
124
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any, scheduleTime: any): void;
124
125
  setPitchBend(channelNumber: any, value: any, scheduleTime: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA6FA;IA0BE;;;;;;;;;;;MAWE;IAEF,+BAeC;IArDD,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAgBnC,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IAMnD,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAWC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDASC;IAED,4DASC;IAED,yEAoDC;IAED,mCAOC;IAED,uBASC;IAED,yDA2BC;IAED,2BA8CC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAKC;IAED,uBAQC;IAED,wBAKC;IAED,0BAKC;IAED,wBAOC;IAED,sBAIC;IAED,yDAQC;IAED,yEASC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDAsBC;IAED,kEAoBC;IAED,4GAkCC;IAED,uEAwCC;IAED,0EAiBC;IAED,oEASC;IAED,0FAwBC;IAED,gCASC;IAED,iEAqBC;IAED,gHAqBC;IAED,6CAUC;IAED,qDAUC;IAED,4GAeC;IAED,+BAmBC;IAED,kDAOC;IAED,sGA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAYC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MAiCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDAUC;IAED,iFAKC;IAED,oEAKC;IAED;;;MAMC;IAED,8DAKC;IAED,4EAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,2DAMC;IAED,uDAkBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,iEAMC;IAED,uEAQC;IAED,mEAKC;IAED,yEAQC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCASC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
1
+ {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA+FA;IA2BE;;;;;;;;;;;MAWE;IAEF,+BAgBC;IAvDD,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,cAAa;IACb,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAiBnC,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IAMnD,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAWC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDASC;IAED,4DASC;IAED,gEAoDC;IAED,mCAOC;IAED,uBASC;IAED,yDAgCC;IAED,2BAyEC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAIC;IAED,uBAMC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAIC;IAED,kEAWC;IAED,kFAYC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDAsBC;IAED,kEAoBC;IAED,4GAkCC;IAED,uEAwCC;IAED,0EAiBC;IAED,oEASC;IAED,0FAoBC;IAED,gCASC;IAED,iEAqBC;IAED,4FAmBC;IAED,6CAUC;IAED,qDAUC;IAED,qFAeC;IAED,+BAmBC;IAED,kDAOC;IAED,sFA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAYC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MAiCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDAUC;IAED,iFAKC;IAED,oEAKC;IAED;;;MAMC;IAED,8DAKC;IAED,4EAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,2DAMC;IAED,uDAkBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,iEAMC;IAED,uEAQC;IAED,mEAKC;IAED,yEAQC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCASC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
@@ -29,12 +29,6 @@ class Note {
29
29
  writable: true,
30
30
  value: false
31
31
  });
32
- Object.defineProperty(this, "pending", {
33
- enumerable: true,
34
- configurable: true,
35
- writable: true,
36
- value: true
37
- });
38
32
  Object.defineProperty(this, "bufferSource", {
39
33
  enumerable: true,
40
34
  configurable: true,
@@ -80,6 +74,9 @@ class Note {
80
74
  this.noteNumber = noteNumber;
81
75
  this.velocity = velocity;
82
76
  this.startTime = startTime;
77
+ this.ready = new Promise((resolve) => {
78
+ this.resolveReady = resolve;
79
+ });
83
80
  }
84
81
  }
85
82
  // normalized to 0-1 for use with the SF2 modulator model
@@ -153,8 +150,9 @@ const pitchEnvelopeKeys = [
153
150
  "playbackRate",
154
151
  ];
155
152
  const pitchEnvelopeKeySet = new Set(pitchEnvelopeKeys);
156
- class MidyGM1 {
153
+ class MidyGM1 extends EventTarget {
157
154
  constructor(audioContext) {
155
+ super();
158
156
  Object.defineProperty(this, "mode", {
159
157
  enumerable: true,
160
158
  configurable: true,
@@ -269,6 +267,12 @@ class MidyGM1 {
269
267
  writable: true,
270
268
  value: false
271
269
  });
270
+ Object.defineProperty(this, "loop", {
271
+ enumerable: true,
272
+ configurable: true,
273
+ writable: true,
274
+ value: false
275
+ });
272
276
  Object.defineProperty(this, "playPromise", {
273
277
  enumerable: true,
274
278
  configurable: true,
@@ -456,7 +460,7 @@ class MidyGM1 {
456
460
  }
457
461
  return bufferSource;
458
462
  }
459
- async scheduleTimelineEvents(scheduleTime, queueIndex) {
463
+ scheduleTimelineEvents(scheduleTime, queueIndex) {
460
464
  const timeOffset = this.resumeTime - this.startTime;
461
465
  const lookAheadCheckTime = scheduleTime + timeOffset + this.lookAhead;
462
466
  const schedulingOffset = this.startDelay - timeOffset;
@@ -468,7 +472,7 @@ class MidyGM1 {
468
472
  const startTime = event.startTime + schedulingOffset;
469
473
  switch (event.type) {
470
474
  case "noteOn":
471
- await this.noteOn(event.channel, event.noteNumber, event.velocity, startTime);
475
+ this.noteOn(event.channel, event.noteNumber, event.velocity, startTime);
472
476
  break;
473
477
  case "noteOff": {
474
478
  this.noteOff(event.channel, event.noteNumber, event.velocity, startTime, false);
@@ -509,22 +513,23 @@ class MidyGM1 {
509
513
  }
510
514
  }
511
515
  updateStates(queueIndex, nextQueueIndex) {
516
+ const now = this.audioContext.currentTime;
512
517
  if (nextQueueIndex < queueIndex)
513
518
  queueIndex = 0;
514
519
  for (let i = queueIndex; i < nextQueueIndex; i++) {
515
520
  const event = this.timeline[i];
516
521
  switch (event.type) {
517
522
  case "controller":
518
- this.setControlChange(event.channel, event.controllerType, event.value, 0);
523
+ this.setControlChange(event.channel, event.controllerType, event.value, now - this.resumeTime + event.startTime);
519
524
  break;
520
525
  case "programChange":
521
- this.setProgramChange(event.channel, event.programNumber, 0);
526
+ this.setProgramChange(event.channel, event.programNumber, now - this.resumeTime + event.startTime);
522
527
  break;
523
528
  case "pitchBend":
524
- this.setPitchBend(event.channel, event.value + 8192, 0);
529
+ this.setPitchBend(event.channel, event.value + 8192, now - this.resumeTime + event.startTime);
525
530
  break;
526
531
  case "sysEx":
527
- this.handleSysEx(event.data, 0);
532
+ this.handleSysEx(event.data, now - this.resumeTime + event.startTime);
528
533
  }
529
534
  }
530
535
  }
@@ -532,50 +537,80 @@ class MidyGM1 {
532
537
  if (this.audioContext.state === "suspended") {
533
538
  await this.audioContext.resume();
534
539
  }
540
+ const paused = this.isPaused;
535
541
  this.isPlaying = true;
536
542
  this.isPaused = false;
537
543
  this.startTime = this.audioContext.currentTime;
544
+ if (paused) {
545
+ this.dispatchEvent(new Event("resumed"));
546
+ }
547
+ else {
548
+ this.dispatchEvent(new Event("started"));
549
+ }
538
550
  let queueIndex = this.getQueueIndex(this.resumeTime);
539
- let finished = false;
551
+ let exitReason;
540
552
  this.notePromises = [];
541
- while (queueIndex < this.timeline.length) {
553
+ while (true) {
542
554
  const now = this.audioContext.currentTime;
555
+ if (this.timeline.length <= queueIndex) {
556
+ await this.stopNotes(0, true, now);
557
+ if (this.loop) {
558
+ this.notePromises = [];
559
+ this.resetAllStates();
560
+ this.startTime = this.audioContext.currentTime;
561
+ this.resumeTime = 0;
562
+ queueIndex = 0;
563
+ this.dispatchEvent(new Event("looped"));
564
+ continue;
565
+ }
566
+ else {
567
+ await this.audioContext.suspend();
568
+ exitReason = "ended";
569
+ break;
570
+ }
571
+ }
543
572
  if (this.isPausing) {
544
573
  await this.stopNotes(0, true, now);
545
574
  await this.audioContext.suspend();
546
575
  this.notePromises = [];
576
+ this.isPausing = false;
577
+ exitReason = "paused";
547
578
  break;
548
579
  }
549
580
  else if (this.isStopping) {
550
581
  await this.stopNotes(0, true, now);
551
582
  await this.audioContext.suspend();
552
- finished = true;
583
+ this.isStopping = false;
584
+ exitReason = "stopped";
553
585
  break;
554
586
  }
555
587
  else if (this.isSeeking) {
556
- await this.stopNotes(0, true, now);
588
+ this.stopNotes(0, true, now);
557
589
  this.startTime = this.audioContext.currentTime;
558
590
  const nextQueueIndex = this.getQueueIndex(this.resumeTime);
559
591
  this.updateStates(queueIndex, nextQueueIndex);
560
592
  queueIndex = nextQueueIndex;
561
593
  this.isSeeking = false;
594
+ this.dispatchEvent(new Event("seeked"));
562
595
  continue;
563
596
  }
564
- queueIndex = await this.scheduleTimelineEvents(now, queueIndex);
597
+ queueIndex = this.scheduleTimelineEvents(now, queueIndex);
565
598
  const waitTime = now + this.noteCheckInterval;
566
599
  await this.scheduleTask(() => { }, waitTime);
567
600
  }
568
- if (this.timeline.length <= queueIndex) {
569
- const now = this.audioContext.currentTime;
570
- await this.stopNotes(0, true, now);
571
- await this.audioContext.suspend();
572
- finished = true;
573
- }
574
- if (finished) {
601
+ if (exitReason !== "paused") {
575
602
  this.notePromises = [];
576
603
  this.resetAllStates();
577
604
  }
578
605
  this.isPlaying = false;
606
+ if (exitReason === "paused") {
607
+ this.isPaused = true;
608
+ this.dispatchEvent(new Event("paused"));
609
+ }
610
+ else {
611
+ this.isPaused = false;
612
+ this.dispatchEvent(new Event(exitReason));
613
+ }
579
614
  }
580
615
  ticksToSecond(ticks, secondsPerBeat) {
581
616
  return ticks * secondsPerBeat / this.ticksPerBeat;
@@ -682,24 +717,20 @@ class MidyGM1 {
682
717
  return;
683
718
  this.isStopping = true;
684
719
  await this.playPromise;
685
- this.isStopping = false;
686
720
  }
687
721
  async pause() {
688
722
  if (!this.isPlaying || this.isPaused)
689
723
  return;
690
724
  const now = this.audioContext.currentTime;
691
- this.resumeTime = now - this.startTime - this.startDelay;
725
+ this.resumeTime = now + this.resumeTime - this.startTime;
692
726
  this.isPausing = true;
693
727
  await this.playPromise;
694
- this.isPausing = false;
695
- this.isPaused = true;
696
728
  }
697
729
  async resume() {
698
730
  if (!this.isPaused)
699
731
  return;
700
732
  this.playPromise = this.playNotes();
701
733
  await this.playPromise;
702
- this.isPaused = false;
703
734
  }
704
735
  seekTo(second) {
705
736
  this.resumeTime = second;
@@ -722,19 +753,23 @@ class MidyGM1 {
722
753
  const now = this.audioContext.currentTime;
723
754
  return now + this.resumeTime - this.startTime;
724
755
  }
725
- processScheduledNotes(channel, callback) {
756
+ async processScheduledNotes(channel, callback) {
726
757
  const scheduledNotes = channel.scheduledNotes;
758
+ const tasks = [];
727
759
  for (let i = channel.scheduleIndex; i < scheduledNotes.length; i++) {
728
760
  const note = scheduledNotes[i];
729
761
  if (!note)
730
762
  continue;
731
763
  if (note.ending)
732
764
  continue;
733
- callback(note);
765
+ const task = note.ready.then(() => callback(note));
766
+ tasks.push(task);
734
767
  }
768
+ await Promise.all(tasks);
735
769
  }
736
- processActiveNotes(channel, scheduleTime, callback) {
770
+ async processActiveNotes(channel, scheduleTime, callback) {
737
771
  const scheduledNotes = channel.scheduledNotes;
772
+ const tasks = [];
738
773
  for (let i = channel.scheduleIndex; i < scheduledNotes.length; i++) {
739
774
  const note = scheduledNotes[i];
740
775
  if (!note)
@@ -743,8 +778,10 @@ class MidyGM1 {
743
778
  continue;
744
779
  if (scheduleTime < note.startTime)
745
780
  break;
746
- callback(note);
781
+ const task = note.ready.then(() => callback(note));
782
+ tasks.push(task);
747
783
  }
784
+ await Promise.all(tasks);
748
785
  }
749
786
  cbToRatio(cb) {
750
787
  return Math.pow(10, cb / 200);
@@ -966,11 +1003,7 @@ class MidyGM1 {
966
1003
  return;
967
1004
  await this.setNoteAudioNode(channel, note, realtime);
968
1005
  this.setNoteRouting(channelNumber, note, startTime);
969
- note.pending = false;
970
- const off = note.offEvent;
971
- if (off) {
972
- this.noteOff(channelNumber, noteNumber, off.velocity, off.startTime);
973
- }
1006
+ note.resolveReady();
974
1007
  }
975
1008
  disconnectNote(note) {
976
1009
  note.bufferSource.disconnect();
@@ -1004,7 +1037,7 @@ class MidyGM1 {
1004
1037
  }, stopTime);
1005
1038
  });
1006
1039
  }
1007
- noteOff(channelNumber, noteNumber, velocity, endTime, force) {
1040
+ noteOff(channelNumber, noteNumber, _velocity, endTime, force) {
1008
1041
  const channel = this.channels[channelNumber];
1009
1042
  if (!force && 0.5 <= channel.state.sustainPedal)
1010
1043
  return;
@@ -1012,13 +1045,11 @@ class MidyGM1 {
1012
1045
  if (index < 0)
1013
1046
  return;
1014
1047
  const note = channel.scheduledNotes[index];
1015
- if (note.pending) {
1016
- note.offEvent = { velocity, startTime: endTime };
1017
- return;
1018
- }
1019
1048
  note.ending = true;
1020
1049
  this.setNoteIndex(channel, index);
1021
- const promise = this.releaseNote(channel, note, endTime);
1050
+ const promise = note.ready.then(() => {
1051
+ return this.releaseNote(channel, note, endTime);
1052
+ });
1022
1053
  this.notePromises.push(promise);
1023
1054
  return promise;
1024
1055
  }
@@ -1106,7 +1137,8 @@ class MidyGM1 {
1106
1137
  }
1107
1138
  setPitchBend(channelNumber, value, scheduleTime) {
1108
1139
  const channel = this.channels[channelNumber];
1109
- scheduleTime ??= this.audioContext.currentTime;
1140
+ if (!(0 <= scheduleTime))
1141
+ scheduleTime = this.audioContext.currentTime;
1110
1142
  const state = channel.state;
1111
1143
  const prev = state.pitchWheel * 2 - 1;
1112
1144
  const next = (value - 8192) / 8192;
@@ -1271,12 +1303,14 @@ class MidyGM1 {
1271
1303
  }
1272
1304
  setModulationDepth(channelNumber, modulation, scheduleTime) {
1273
1305
  const channel = this.channels[channelNumber];
1274
- scheduleTime ??= this.audioContext.currentTime;
1306
+ if (!(0 <= scheduleTime))
1307
+ scheduleTime = this.audioContext.currentTime;
1275
1308
  channel.state.modulationDepthMSB = modulation / 127;
1276
1309
  this.updateModulation(channel, scheduleTime);
1277
1310
  }
1278
1311
  setVolume(channelNumber, volume, scheduleTime) {
1279
- scheduleTime ??= this.audioContext.currentTime;
1312
+ if (!(0 <= scheduleTime))
1313
+ scheduleTime = this.audioContext.currentTime;
1280
1314
  const channel = this.channels[channelNumber];
1281
1315
  channel.state.volumeMSB = volume / 127;
1282
1316
  this.updateChannelVolume(channel, scheduleTime);
@@ -1289,13 +1323,15 @@ class MidyGM1 {
1289
1323
  };
1290
1324
  }
1291
1325
  setPan(channelNumber, pan, scheduleTime) {
1292
- scheduleTime ??= this.audioContext.currentTime;
1326
+ if (!(0 <= scheduleTime))
1327
+ scheduleTime = this.audioContext.currentTime;
1293
1328
  const channel = this.channels[channelNumber];
1294
1329
  channel.state.panMSB = pan / 127;
1295
1330
  this.updateChannelVolume(channel, scheduleTime);
1296
1331
  }
1297
1332
  setExpression(channelNumber, expression, scheduleTime) {
1298
- scheduleTime ??= this.audioContext.currentTime;
1333
+ if (!(0 <= scheduleTime))
1334
+ scheduleTime = this.audioContext.currentTime;
1299
1335
  const channel = this.channels[channelNumber];
1300
1336
  channel.state.expressionMSB = expression / 127;
1301
1337
  this.updateChannelVolume(channel, scheduleTime);
@@ -1317,7 +1353,8 @@ class MidyGM1 {
1317
1353
  }
1318
1354
  setSustainPedal(channelNumber, value, scheduleTime) {
1319
1355
  const channel = this.channels[channelNumber];
1320
- scheduleTime ??= this.audioContext.currentTime;
1356
+ if (!(0 <= scheduleTime))
1357
+ scheduleTime = this.audioContext.currentTime;
1321
1358
  channel.state.sustainPedal = value / 127;
1322
1359
  if (64 <= value) {
1323
1360
  this.processScheduledNotes(channel, (note) => {
@@ -1389,7 +1426,8 @@ class MidyGM1 {
1389
1426
  }
1390
1427
  setPitchBendRange(channelNumber, value, scheduleTime) {
1391
1428
  const channel = this.channels[channelNumber];
1392
- scheduleTime ??= this.audioContext.currentTime;
1429
+ if (!(0 <= scheduleTime))
1430
+ scheduleTime = this.audioContext.currentTime;
1393
1431
  const state = channel.state;
1394
1432
  const prev = state.pitchWheelSensitivity;
1395
1433
  const next = value / 12800;
@@ -1407,7 +1445,8 @@ class MidyGM1 {
1407
1445
  }
1408
1446
  setFineTuning(channelNumber, value, scheduleTime) {
1409
1447
  const channel = this.channels[channelNumber];
1410
- scheduleTime ??= this.audioContext.currentTime;
1448
+ if (!(0 <= scheduleTime))
1449
+ scheduleTime = this.audioContext.currentTime;
1411
1450
  const prev = channel.fineTuning;
1412
1451
  const next = value;
1413
1452
  channel.fineTuning = next;
@@ -1422,7 +1461,8 @@ class MidyGM1 {
1422
1461
  }
1423
1462
  setCoarseTuning(channelNumber, value, scheduleTime) {
1424
1463
  const channel = this.channels[channelNumber];
1425
- scheduleTime ??= this.audioContext.currentTime;
1464
+ if (!(0 <= scheduleTime))
1465
+ scheduleTime = this.audioContext.currentTime;
1426
1466
  const prev = channel.coarseTuning;
1427
1467
  const next = value;
1428
1468
  channel.coarseTuning = next;
@@ -1430,7 +1470,8 @@ class MidyGM1 {
1430
1470
  this.updateChannelDetune(channel, scheduleTime);
1431
1471
  }
1432
1472
  allSoundOff(channelNumber, _value, scheduleTime) {
1433
- scheduleTime ??= this.audioContext.currentTime;
1473
+ if (!(0 <= scheduleTime))
1474
+ scheduleTime = this.audioContext.currentTime;
1434
1475
  return this.stopActiveNotes(channelNumber, 0, true, scheduleTime);
1435
1476
  }
1436
1477
  resetChannelStates(channelNumber) {
@@ -1482,7 +1523,8 @@ class MidyGM1 {
1482
1523
  }
1483
1524
  }
1484
1525
  allNotesOff(channelNumber, _value, scheduleTime) {
1485
- scheduleTime ??= this.audioContext.currentTime;
1526
+ if (!(0 <= scheduleTime))
1527
+ scheduleTime = this.audioContext.currentTime;
1486
1528
  return this.stopActiveNotes(channelNumber, 0, false, scheduleTime);
1487
1529
  }
1488
1530
  handleUniversalNonRealTimeExclusiveMessage(data, scheduleTime) {
@@ -1503,7 +1545,8 @@ class MidyGM1 {
1503
1545
  }
1504
1546
  }
1505
1547
  GM1SystemOn(scheduleTime) {
1506
- scheduleTime ??= this.audioContext.currentTime;
1548
+ if (!(0 <= scheduleTime))
1549
+ scheduleTime = this.audioContext.currentTime;
1507
1550
  this.mode = "GM1";
1508
1551
  for (let i = 0; i < this.channels.length; i++) {
1509
1552
  this.allSoundOff(i, 0, scheduleTime);
@@ -1531,7 +1574,8 @@ class MidyGM1 {
1531
1574
  this.setMasterVolume(volume, scheduleTime);
1532
1575
  }
1533
1576
  setMasterVolume(value, scheduleTime) {
1534
- scheduleTime ??= this.audioContext.currentTime;
1577
+ if (!(0 <= scheduleTime))
1578
+ scheduleTime = this.audioContext.currentTime;
1535
1579
  this.masterVolume.gain
1536
1580
  .cancelScheduledValues(scheduleTime)
1537
1581
  .setValueAtTime(value * value, scheduleTime);
@@ -1,4 +1,4 @@
1
- export class MidyGM2 {
1
+ export class MidyGM2 extends EventTarget {
2
2
  static channelSettings: {
3
3
  scheduleIndex: number;
4
4
  detune: number;
@@ -50,6 +50,7 @@ export class MidyGM2 {
50
50
  isPaused: boolean;
51
51
  isStopping: boolean;
52
52
  isSeeking: boolean;
53
+ loop: boolean;
53
54
  playPromise: any;
54
55
  timeline: any[];
55
56
  notePromises: any[];
@@ -105,7 +106,7 @@ export class MidyGM2 {
105
106
  createAudioBuffer(voiceParams: any): Promise<any>;
106
107
  isLoopDrum(channel: any, noteNumber: any): boolean;
107
108
  createBufferSource(channel: any, noteNumber: any, voiceParams: any, audioBuffer: any): any;
108
- scheduleTimelineEvents(scheduleTime: any, queueIndex: any): Promise<any>;
109
+ scheduleTimelineEvents(scheduleTime: any, queueIndex: any): any;
109
110
  getQueueIndex(second: any): number;
110
111
  resetAllStates(): void;
111
112
  updateStates(queueIndex: any, nextQueueIndex: any): void;
@@ -127,8 +128,8 @@ export class MidyGM2 {
127
128
  seekTo(second: any): void;
128
129
  calcTotalTime(): number;
129
130
  currentTime(): number;
130
- processScheduledNotes(channel: any, callback: any): void;
131
- processActiveNotes(channel: any, scheduleTime: any, callback: any): void;
131
+ processScheduledNotes(channel: any, callback: any): Promise<void>;
132
+ processActiveNotes(channel: any, scheduleTime: any, callback: any): Promise<void>;
132
133
  createConvolutionReverbImpulse(audioContext: any, decay: any, preDecay: any): any;
133
134
  createConvolutionReverb(audioContext: any, impulse: any): {
134
135
  input: any;
@@ -182,11 +183,11 @@ export class MidyGM2 {
182
183
  noteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
183
184
  disconnectNote(note: any): void;
184
185
  releaseNote(channel: any, note: any, endTime: any): Promise<any>;
185
- noteOff(channelNumber: any, noteNumber: any, velocity: any, endTime: any, force: any): Promise<any> | undefined;
186
+ noteOff(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, force: any): any;
186
187
  setNoteIndex(channel: any, index: any): void;
187
188
  findNoteOffIndex(channel: any, noteNumber: any): any;
188
- releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
189
- releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
189
+ releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): any[];
190
+ releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): any[];
190
191
  createMessageHandlers(): any[];
191
192
  handleMessage(data: any, scheduleTime: any): void;
192
193
  activeSensing(): void;
@@ -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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"}