@marmooo/midy 0.0.1 → 0.0.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.
@@ -8,12 +8,6 @@ export class MidyGMLite {
8
8
  writable: true,
9
9
  value: 120
10
10
  });
11
- Object.defineProperty(this, "secondsPerBeat", {
12
- enumerable: true,
13
- configurable: true,
14
- writable: true,
15
- value: 0.5
16
- });
17
11
  Object.defineProperty(this, "totalTime", {
18
12
  enumerable: true,
19
13
  configurable: true,
@@ -144,10 +138,10 @@ export class MidyGMLite {
144
138
  const response = await fetch(midiUrl);
145
139
  const arrayBuffer = await response.arrayBuffer();
146
140
  const midi = parseMidi(new Uint8Array(arrayBuffer));
141
+ this.ticksPerBeat = midi.header.ticksPerBeat;
147
142
  const midiData = this.extractMidiData(midi);
148
143
  this.instruments = midiData.instruments;
149
144
  this.timeline = midiData.timeline;
150
- this.ticksPerBeat = midi.header.ticksPerBeat;
151
145
  this.totalTime = this.calcTotalTime();
152
146
  }
153
147
  setChannelAudioNodes(audioContext) {
@@ -226,18 +220,20 @@ export class MidyGMLite {
226
220
  async scheduleTimelineEvents(t, offset, queueIndex) {
227
221
  while (queueIndex < this.timeline.length) {
228
222
  const event = this.timeline[queueIndex];
229
- const time = this.ticksToSecond(event.ticks, this.secondsPerBeat);
230
- if (time > t + this.lookAhead)
223
+ if (event.startTime > t + this.lookAhead)
231
224
  break;
232
225
  switch (event.type) {
233
226
  case "controller":
234
227
  this.handleControlChange(event.channel, event.controllerType, event.value);
235
228
  break;
236
229
  case "noteOn":
237
- await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, time + this.startDelay - offset);
238
- break;
230
+ if (event.velocity !== 0) {
231
+ await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
232
+ break;
233
+ }
234
+ /* falls through */
239
235
  case "noteOff": {
240
- const notePromise = this.scheduleNoteRelease(event.channel, event.noteNumber, event.velocity, time + this.startDelay - offset);
236
+ const notePromise = this.scheduleNoteRelease(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
241
237
  if (notePromise) {
242
238
  this.notePromises.push(notePromise);
243
239
  }
@@ -246,9 +242,6 @@ export class MidyGMLite {
246
242
  case "programChange":
247
243
  this.handleProgramChange(event.channel, event.programNumber);
248
244
  break;
249
- case "setTempo":
250
- this.secondsPerBeat = event.microsecondsPerBeat / 1000000;
251
- break;
252
245
  case "sysEx":
253
246
  this.handleSysEx(event.data);
254
247
  }
@@ -257,9 +250,8 @@ export class MidyGMLite {
257
250
  return queueIndex;
258
251
  }
259
252
  getQueueIndex(second) {
260
- const ticks = this.secondToTicks(second, this.secondsPerBeat);
261
253
  for (let i = 0; i < this.timeline.length; i++) {
262
- if (ticks <= this.timeline[i].ticks) {
254
+ if (second <= this.timeline[i].startTime) {
263
255
  return i;
264
256
  }
265
257
  }
@@ -367,18 +359,28 @@ export class MidyGMLite {
367
359
  timeline.push(event);
368
360
  });
369
361
  });
362
+ const priority = {
363
+ setTempo: 0,
364
+ controller: 1,
365
+ };
370
366
  timeline.sort((a, b) => {
371
- if (a.ticks !== b.ticks) {
367
+ if (a.ticks !== b.ticks)
372
368
  return a.ticks - b.ticks;
373
- }
374
- if (a.type !== "controller" && b.type === "controller") {
375
- return -1;
376
- }
377
- if (a.type === "controller" && b.type !== "controller") {
378
- return 1;
379
- }
380
- return 0;
369
+ return (priority[a.type] || 2) - (priority[b.type] || 2);
381
370
  });
371
+ let prevTempoTime = 0;
372
+ let prevTempoTicks = 0;
373
+ let secondsPerBeat = 0.5;
374
+ for (let i = 0; i < timeline.length; i++) {
375
+ const event = timeline[i];
376
+ const timeFromPrevTempo = this.ticksToSecond(event.ticks - prevTempoTicks, secondsPerBeat);
377
+ event.startTime = prevTempoTime + timeFromPrevTempo;
378
+ if (event.type === "setTempo") {
379
+ prevTempoTime += this.ticksToSecond(event.ticks - prevTempoTicks, secondsPerBeat);
380
+ secondsPerBeat = event.microsecondsPerBeat / 1000000;
381
+ prevTempoTicks = event.ticks;
382
+ }
383
+ }
382
384
  return { instruments, timeline };
383
385
  }
384
386
  stopNotes() {
@@ -430,32 +432,12 @@ export class MidyGMLite {
430
432
  }
431
433
  }
432
434
  calcTotalTime() {
433
- const endOfTracks = [];
434
- let prevTicks = 0;
435
435
  let totalTime = 0;
436
- let secondsPerBeat = 0.5;
437
436
  for (let i = 0; i < this.timeline.length; i++) {
438
437
  const event = this.timeline[i];
439
- switch (event.type) {
440
- case "setTempo": {
441
- const durationTicks = event.ticks - prevTicks;
442
- totalTime += this.ticksToSecond(durationTicks, secondsPerBeat);
443
- secondsPerBeat = event.microsecondsPerBeat / 1000000;
444
- prevTicks = event.ticks;
445
- break;
446
- }
447
- case "endOfTrack":
448
- endOfTracks.push(event);
449
- }
438
+ if (totalTime < event.startTime)
439
+ totalTime = event.startTime;
450
440
  }
451
- let maxTicks = 0;
452
- for (let i = 0; i < endOfTracks.length; i++) {
453
- const event = endOfTracks[i];
454
- if (maxTicks < event.ticks)
455
- maxTicks = event.ticks;
456
- }
457
- const durationTicks = maxTicks - prevTicks;
458
- totalTime += this.ticksToSecond(durationTicks, secondsPerBeat);
459
441
  return totalTime;
460
442
  }
461
443
  currentTime() {
@@ -464,7 +446,7 @@ export class MidyGMLite {
464
446
  }
465
447
  getActiveNotes(channel) {
466
448
  const activeNotes = new Map();
467
- channel.scheduledNotes.forEeach((scheduledNotes) => {
449
+ channel.scheduledNotes.forEach((scheduledNotes) => {
468
450
  const activeNote = this.getActiveChannelNotes(scheduledNotes);
469
451
  if (activeNote) {
470
452
  activeNotes.set(activeNote.noteNumber, activeNote);
@@ -483,43 +465,8 @@ export class MidyGMLite {
483
465
  const lfo = new OscillatorNode(audioContext, {
484
466
  frequency: 5,
485
467
  });
486
- const lfoGain = new GainNode(audioContext);
487
- lfo.connect(lfoGain);
488
468
  return {
489
469
  lfo,
490
- lfoGain,
491
- };
492
- }
493
- createReverbEffect(audioContext, options = {}) {
494
- const { decay = 0.8, preDecay = 0, } = options;
495
- const sampleRate = audioContext.sampleRate;
496
- const length = sampleRate * decay;
497
- const impulse = new AudioBuffer({
498
- numberOfChannels: 2,
499
- length,
500
- sampleRate,
501
- });
502
- const preDecayLength = Math.min(sampleRate * preDecay, length);
503
- for (let channel = 0; channel < impulse.numberOfChannels; channel++) {
504
- const channelData = impulse.getChannelData(channel);
505
- for (let i = 0; i < preDecayLength; i++) {
506
- channelData[i] = Math.random() * 2 - 1;
507
- }
508
- for (let i = preDecayLength; i < length; i++) {
509
- const attenuation = Math.exp(-(i - preDecayLength) / sampleRate / decay);
510
- channelData[i] = (Math.random() * 2 - 1) * attenuation;
511
- }
512
- }
513
- const convolverNode = new ConvolverNode(audioContext, {
514
- buffer: impulse,
515
- });
516
- const dryGain = new GainNode(audioContext);
517
- const wetGain = new GainNode(audioContext);
518
- convolverNode.connect(wetGain);
519
- return {
520
- convolverNode,
521
- dryGain,
522
- wetGain,
523
470
  };
524
471
  }
525
472
  connectNoteEffects(channel, gainNode) {
@@ -543,7 +490,7 @@ export class MidyGMLite {
543
490
  });
544
491
  let volume = (velocity / 127) * channel.volume * channel.expression;
545
492
  if (volume === 0)
546
- volume = 1e-6; // exponentialRampToValueAtTime() requirea a non-zero value
493
+ volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
547
494
  const attackVolume = this.cbToRatio(-noteInfo.initialAttenuation) * volume;
548
495
  const sustainVolume = attackVolume * (1 - noteInfo.volSustain);
549
496
  const volDelay = startTime + noteInfo.volDelay;
@@ -555,35 +502,46 @@ export class MidyGMLite {
555
502
  .exponentialRampToValueAtTime(attackVolume, volAttack)
556
503
  .setValueAtTime(attackVolume, volHold)
557
504
  .linearRampToValueAtTime(sustainVolume, volDecay);
558
- if (channel.modulation > 0) {
559
- const lfoGain = channel.modulationEffect.lfoGain;
560
- lfoGain.connect(bufferSource.detune);
561
- lfoGain.gain.cancelScheduledValues(startTime + channel.vibratoDelay);
562
- lfoGain.gain.setValueAtTime(channel.modulation, startTime + channel.vibratoDelay);
563
- }
564
505
  // filter envelope
506
+ const maxFreq = this.audioContext.sampleRate / 2;
565
507
  const baseFreq = this.centToHz(noteInfo.initialFilterFc);
566
508
  const peekFreq = this.centToHz(noteInfo.initialFilterFc + noteInfo.modEnvToFilterFc);
567
509
  const sustainFreq = baseFreq +
568
510
  (peekFreq - baseFreq) * (1 - noteInfo.modSustain);
511
+ const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
512
+ const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
513
+ const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
569
514
  const filterNode = new BiquadFilterNode(this.audioContext, {
570
515
  type: "lowpass",
571
- Q: this.cbToRatio(noteInfo.initialFilterQ),
572
- frequency: baseFreq,
516
+ Q: noteInfo.initialFilterQ / 10, // dB
517
+ frequency: adjustedBaseFreq,
573
518
  });
574
519
  const modDelay = startTime + noteInfo.modDelay;
575
520
  const modAttack = modDelay + noteInfo.modAttack;
576
521
  const modHold = modAttack + noteInfo.modHold;
577
522
  const modDecay = modHold + noteInfo.modDecay;
578
523
  filterNode.frequency
579
- .setValueAtTime(baseFreq, modDelay)
580
- .exponentialRampToValueAtTime(peekFreq, modAttack)
581
- .setValueAtTime(peekFreq, modHold)
582
- .linearRampToValueAtTime(sustainFreq, modDecay);
524
+ .setValueAtTime(adjustedBaseFreq, modDelay)
525
+ .exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
526
+ .setValueAtTime(adjustedPeekFreq, modHold)
527
+ .linearRampToValueAtTime(adjustedSustainFreq, modDecay);
528
+ let lfoGain;
529
+ if (channel.modulation > 0) {
530
+ const vibratoDelay = startTime + channel.vibratoDelay;
531
+ const vibratoAttack = vibratoDelay + 0.1;
532
+ lfoGain = new GainNode(this.audioContext, {
533
+ gain: 0,
534
+ });
535
+ lfoGain.gain
536
+ .setValueAtTime(1e-6, vibratoDelay) // exponentialRampToValueAtTime() requires a non-zero value
537
+ .exponentialRampToValueAtTime(channel.modulation, vibratoAttack);
538
+ channel.modulationEffect.lfo.connect(lfoGain);
539
+ lfoGain.connect(bufferSource.detune);
540
+ }
583
541
  bufferSource.connect(filterNode);
584
542
  filterNode.connect(gainNode);
585
543
  bufferSource.start(startTime, noteInfo.start / noteInfo.sampleRate);
586
- return { bufferSource, gainNode, filterNode };
544
+ return { bufferSource, gainNode, filterNode, lfoGain };
587
545
  }
588
546
  async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
589
547
  const channel = this.channels[channelNumber];
@@ -596,16 +554,17 @@ export class MidyGMLite {
596
554
  const noteInfo = soundFont.getInstrumentKey(bankNumber, channel.program, noteNumber);
597
555
  if (!noteInfo)
598
556
  return;
599
- const { bufferSource, gainNode, filterNode } = await this
557
+ const { bufferSource, gainNode, filterNode, lfoGain } = await this
600
558
  .createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3);
601
559
  this.connectNoteEffects(channel, gainNode);
602
560
  const scheduledNotes = channel.scheduledNotes;
603
561
  const scheduledNote = {
604
- gainNode,
605
- filterNode,
606
562
  bufferSource,
607
- noteNumber,
563
+ filterNode,
564
+ gainNode,
565
+ lfoGain,
608
566
  noteInfo,
567
+ noteNumber,
609
568
  startTime,
610
569
  };
611
570
  if (scheduledNotes.has(noteNumber)) {
@@ -632,15 +591,18 @@ export class MidyGMLite {
632
591
  continue;
633
592
  if (targetNote.ending)
634
593
  continue;
635
- const { bufferSource, filterNode, gainNode, noteInfo } = targetNote;
594
+ const { bufferSource, filterNode, gainNode, lfoGain, noteInfo } = targetNote;
636
595
  const velocityRate = (velocity + 127) / 127;
637
596
  const volEndTime = stopTime + noteInfo.volRelease * velocityRate;
638
597
  gainNode.gain.cancelScheduledValues(stopTime);
639
598
  gainNode.gain.linearRampToValueAtTime(0, volEndTime);
599
+ const maxFreq = this.audioContext.sampleRate / 2;
640
600
  const baseFreq = this.centToHz(noteInfo.initialFilterFc);
601
+ const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
641
602
  const modEndTime = stopTime + noteInfo.modRelease * velocityRate;
642
- filterNode.frequency.cancelScheduledValues(stopTime);
643
- filterNode.frequency.linearRampToValueAtTime(baseFreq, modEndTime);
603
+ filterNode.frequency
604
+ .cancelScheduledValues(stopTime)
605
+ .linearRampToValueAtTime(adjustedBaseFreq, modEndTime);
644
606
  targetNote.ending = true;
645
607
  this.scheduleTask(() => {
646
608
  bufferSource.loop = false;
@@ -651,6 +613,8 @@ export class MidyGMLite {
651
613
  bufferSource.disconnect(0);
652
614
  filterNode.disconnect(0);
653
615
  gainNode.disconnect(0);
616
+ if (lfoGain)
617
+ lfoGain.disconnect(0);
654
618
  resolve();
655
619
  };
656
620
  bufferSource.stop(volEndTime);
@@ -661,25 +625,21 @@ export class MidyGMLite {
661
625
  const now = this.audioContext.currentTime;
662
626
  return this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now);
663
627
  }
664
- releaseSustainPedal(channelNumber) {
665
- const now = this.audioContext.currentTime;
628
+ releaseSustainPedal(channelNumber, halfVelocity) {
629
+ const velocity = halfVelocity * 2;
666
630
  const channel = this.channels[channelNumber];
631
+ const promises = [];
667
632
  channel.sustainPedal = false;
668
633
  channel.scheduledNotes.forEach((scheduledNotes) => {
669
634
  scheduledNotes.forEach((scheduledNote) => {
670
635
  if (scheduledNote) {
671
- const { gainNode, bufferSource, noteInfo } = scheduledNote;
672
- const volEndTime = now + noteInfo.volRelease;
673
- gainNode.gain.cancelScheduledValues(now);
674
- gainNode.gain.linearRampToValueAtTime(0, volEndTime);
675
- const baseFreq = this.centToHz(noteInfo.initialFilterFc);
676
- const modEndTime = stopTime + noteInfo.modRelease;
677
- filterNode.frequency.cancelScheduledValues(stopTime);
678
- filterNode.frequency.linearRampToValueAtTime(baseFreq, modEndTime);
679
- bufferSource.stop(volEndTime);
636
+ const { noteNumber } = scheduledNote;
637
+ const promise = this.releaseNote(channelNumber, noteNumber, velocity);
638
+ promises.push(promise);
680
639
  }
681
640
  });
682
641
  });
642
+ return promises;
683
643
  }
684
644
  handleMIDIMessage(statusByte, data1, data2) {
685
645
  const channelNumber = statusByte & 0x0F;
@@ -712,7 +672,7 @@ export class MidyGMLite {
712
672
  scheduledNotes.forEach((scheduledNote) => {
713
673
  if (scheduledNote) {
714
674
  const { initialAttenuation } = scheduledNote.noteInfo;
715
- const gain = this.cbToRatio(initialAttenuation) * pressure;
675
+ const gain = this.cbToRatio(-initialAttenuation) * pressure;
716
676
  scheduledNote.gainNode.gain.cancelScheduledValues(now);
717
677
  scheduledNote.gainNode.gain.setValueAtTime(gain, now);
718
678
  }
@@ -761,13 +721,9 @@ export class MidyGMLite {
761
721
  }
762
722
  }
763
723
  setModulation(channelNumber, modulation) {
764
- const now = this.audioContext.currentTime;
765
724
  const channel = this.channels[channelNumber];
766
- channel.modulation = (modulation * 100 / 127) *
767
- channel.modulationDepthRange;
768
- const lfoGain = channel.modulationEffect.lfoGain;
769
- lfoGain.gain.cancelScheduledValues(now);
770
- lfoGain.gain.setValueAtTime(channel.modulation, now);
725
+ channel.modulation = (modulation / 127) *
726
+ (channel.modulationDepthRange * 100);
771
727
  }
772
728
  setVolume(channelNumber, volume) {
773
729
  const channel = this.channels[channelNumber];
@@ -793,9 +749,10 @@ export class MidyGMLite {
793
749
  channel.gainNode.gain.setValueAtTime(volume, now);
794
750
  }
795
751
  setSustainPedal(channelNumber, value) {
796
- this.channels[channelNumber].sustainPedal = value >= 64;
752
+ const isOn = value >= 64;
753
+ this.channels[channelNumber].sustainPedal = isOn;
797
754
  if (!isOn) {
798
- this.releaseSustainPedal(channelNumber);
755
+ this.releaseSustainPedal(channelNumber, value);
799
756
  }
800
757
  }
801
758
  setRPNMSB(channelNumber, value) {
@@ -929,7 +886,7 @@ Object.defineProperty(MidyGMLite, "channelSettings", {
929
886
  configurable: true,
930
887
  writable: true,
931
888
  value: {
932
- volume: 1,
889
+ volume: 100 / 127,
933
890
  pan: 0,
934
891
  vibratoRate: 5,
935
892
  vibratoDepth: 0.5,
@@ -939,7 +896,7 @@ Object.defineProperty(MidyGMLite, "channelSettings", {
939
896
  dataLSB: 0,
940
897
  program: 0,
941
898
  pitchBend: 0,
942
- modulationDepthRange: 2,
899
+ modulationDepthRange: 0.5,
943
900
  }
944
901
  });
945
902
  Object.defineProperty(MidyGMLite, "effectSettings", {
package/esm/midy.d.ts CHANGED
@@ -34,7 +34,6 @@ export class Midy {
34
34
  };
35
35
  constructor(audioContext: any);
36
36
  ticksPerBeat: number;
37
- secondsPerBeat: number;
38
37
  totalTime: number;
39
38
  reverbFactor: number;
40
39
  masterFineTuning: number;
@@ -65,7 +64,6 @@ export class Midy {
65
64
  pannerNode: any;
66
65
  modulationEffect: {
67
66
  lfo: any;
68
- lfoGain: any;
69
67
  };
70
68
  reverbEffect: {
71
69
  convolverNode: any;
@@ -117,7 +115,6 @@ export class Midy {
117
115
  pannerNode: any;
118
116
  modulationEffect: {
119
117
  lfo: any;
120
- lfoGain: any;
121
118
  };
122
119
  reverbEffect: {
123
120
  convolverNode: any;
@@ -138,7 +135,6 @@ export class Midy {
138
135
  pannerNode: any;
139
136
  modulationEffect: {
140
137
  lfo: any;
141
- lfoGain: any;
142
138
  };
143
139
  reverbEffect: {
144
140
  convolverNode: any;
@@ -205,7 +201,6 @@ export class Midy {
205
201
  getActiveChannelNotes(scheduledNotes: any): any;
206
202
  createModulationEffect(audioContext: any): {
207
203
  lfo: any;
208
- lfoGain: any;
209
204
  };
210
205
  createReverbEffect(audioContext: any, options?: {}): {
211
206
  convolverNode: any;
@@ -231,8 +226,8 @@ export class Midy {
231
226
  noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
232
227
  scheduleNoteRelease(channelNumber: any, noteNumber: any, velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
233
228
  releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
234
- releaseSustainPedal(channelNumber: any): void;
235
- releaseSostenuto(channelNumber: any): void;
229
+ releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
230
+ releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
236
231
  handleMIDIMessage(statusByte: any, data1: any, data2: any): any;
237
232
  handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
238
233
  handleProgramChange(channelNumber: any, program: any): void;
package/esm/midy.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAMA;IAyBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF,+BAMC;IAjED,qBAAmB;IACnB,uBAAqB;IACrB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IAsChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;;;;;MAuBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EA6CC;IAED,mCAQC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA4FC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBA2BC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;;MAUC;IAED;;;;MAoCC;IAED;;;;;MA2CC;IAED,sDA2BC;IAED,2BAEC;IAED,4BAEC;IAED;;;;OA6EC;IAED,gDAQC;IAED,kGA+CC;IAED,0EAGC;IAED,sIAwCC;IAED,0FAGC;IAED,8CAmBC;IAED,2CAYC;IAED,gEAqBC;IAED,sFAeC;IAED,4DAIC;IAED,+DAEC;IAED,8DAGC;IAED,0EAkEC;IAED,+CAEC;IAED,yDAQC;IAED,iEAEC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,+CAEC;IAED,sCAKC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAQC;IAED,uDAIC;IAED,2DAMC;IAED,6DAMC;IAED,6DASC;IAED,4CAkBC;IAED,4CAkBC;IAED,gDAEC;IAED,gDAEC;IAGD,+DAuBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,sCAIC;IAED,6CAGC;IAED,8CAMC;IAED,+CAGC;IAED,kDAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
1
+ {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAMA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF,+BAMC;IAhED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IAsChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;;;;MAuBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EA4CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA2GC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED;;;;MAoCC;IAED;;;;;MA2CC;IAED,sDA2BC;IAED,2BAEC;IAED,4BAEC;IAED;;;;OAsFC;IAED,gDAQC;IAED,kGAgDC;IAED,0EAGC;IAED,sIA6CC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,gEAqBC;IAED,sFAeC;IAED,4DAIC;IAED,+DAEC;IAED,8DAGC;IAED,0EAkEC;IAED,+CAEC;IAED,yDAIC;IAED,iEAEC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,+CAEC;IAED,sCAKC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAUC;IAED,uDAGC;IAED,2DAOC;IAED,6DAOC;IAED,6DASC;IAED,4CAkBC;IAED,4CAkBC;IAED,gDAEC;IAED,gDAEC;IAGD,+DAuBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,sCAIC;IAED,6CAGC;IAED,8CAMC;IAED,+CAGC;IAED,kDAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}