@marmooo/midy 0.0.2 → 0.0.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.
@@ -11,12 +11,6 @@ class MidyGM1 {
11
11
  writable: true,
12
12
  value: 120
13
13
  });
14
- Object.defineProperty(this, "secondsPerBeat", {
15
- enumerable: true,
16
- configurable: true,
17
- writable: true,
18
- value: 0.5
19
- });
20
14
  Object.defineProperty(this, "totalTime", {
21
15
  enumerable: true,
22
16
  configurable: true,
@@ -147,10 +141,10 @@ class MidyGM1 {
147
141
  const response = await fetch(midiUrl);
148
142
  const arrayBuffer = await response.arrayBuffer();
149
143
  const midi = (0, _esm_js_1.parseMidi)(new Uint8Array(arrayBuffer));
144
+ this.ticksPerBeat = midi.header.ticksPerBeat;
150
145
  const midiData = this.extractMidiData(midi);
151
146
  this.instruments = midiData.instruments;
152
147
  this.timeline = midiData.timeline;
153
- this.ticksPerBeat = midi.header.ticksPerBeat;
154
148
  this.totalTime = this.calcTotalTime();
155
149
  }
156
150
  setChannelAudioNodes(audioContext) {
@@ -229,28 +223,30 @@ class MidyGM1 {
229
223
  async scheduleTimelineEvents(t, offset, queueIndex) {
230
224
  while (queueIndex < this.timeline.length) {
231
225
  const event = this.timeline[queueIndex];
232
- const time = this.ticksToSecond(event.ticks, this.secondsPerBeat);
233
- if (time > t + this.lookAhead)
226
+ if (event.startTime > t + this.lookAhead)
234
227
  break;
235
228
  switch (event.type) {
236
- case "controller":
237
- this.handleControlChange(event.channel, event.controllerType, event.value);
238
- break;
239
229
  case "noteOn":
240
- await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, time + this.startDelay - offset);
241
- 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 */
242
235
  case "noteOff": {
243
- 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);
244
237
  if (notePromise) {
245
238
  this.notePromises.push(notePromise);
246
239
  }
247
240
  break;
248
241
  }
242
+ case "controller":
243
+ this.handleControlChange(event.channel, event.controllerType, event.value);
244
+ break;
249
245
  case "programChange":
250
246
  this.handleProgramChange(event.channel, event.programNumber);
251
247
  break;
252
- case "setTempo":
253
- this.secondsPerBeat = event.microsecondsPerBeat / 1000000;
248
+ case "pitchBend":
249
+ this.handlePitchBend(event.channel, event.value);
254
250
  break;
255
251
  case "sysEx":
256
252
  this.handleSysEx(event.data);
@@ -260,9 +256,8 @@ class MidyGM1 {
260
256
  return queueIndex;
261
257
  }
262
258
  getQueueIndex(second) {
263
- const ticks = this.secondToTicks(second, this.secondsPerBeat);
264
259
  for (let i = 0; i < this.timeline.length; i++) {
265
- if (ticks <= this.timeline[i].ticks) {
260
+ if (second <= this.timeline[i].startTime) {
266
261
  return i;
267
262
  }
268
263
  }
@@ -370,18 +365,28 @@ class MidyGM1 {
370
365
  timeline.push(event);
371
366
  });
372
367
  });
368
+ const priority = {
369
+ setTempo: 0,
370
+ controller: 1,
371
+ };
373
372
  timeline.sort((a, b) => {
374
- if (a.ticks !== b.ticks) {
373
+ if (a.ticks !== b.ticks)
375
374
  return a.ticks - b.ticks;
376
- }
377
- if (a.type !== "controller" && b.type === "controller") {
378
- return -1;
379
- }
380
- if (a.type === "controller" && b.type !== "controller") {
381
- return 1;
382
- }
383
- return 0;
375
+ return (priority[a.type] || 2) - (priority[b.type] || 2);
384
376
  });
377
+ let prevTempoTime = 0;
378
+ let prevTempoTicks = 0;
379
+ let secondsPerBeat = 0.5;
380
+ for (let i = 0; i < timeline.length; i++) {
381
+ const event = timeline[i];
382
+ const timeFromPrevTempo = this.ticksToSecond(event.ticks - prevTempoTicks, secondsPerBeat);
383
+ event.startTime = prevTempoTime + timeFromPrevTempo;
384
+ if (event.type === "setTempo") {
385
+ prevTempoTime += this.ticksToSecond(event.ticks - prevTempoTicks, secondsPerBeat);
386
+ secondsPerBeat = event.microsecondsPerBeat / 1000000;
387
+ prevTempoTicks = event.ticks;
388
+ }
389
+ }
385
390
  return { instruments, timeline };
386
391
  }
387
392
  stopNotes() {
@@ -433,32 +438,12 @@ class MidyGM1 {
433
438
  }
434
439
  }
435
440
  calcTotalTime() {
436
- const endOfTracks = [];
437
- let prevTicks = 0;
438
441
  let totalTime = 0;
439
- let secondsPerBeat = 0.5;
440
442
  for (let i = 0; i < this.timeline.length; i++) {
441
443
  const event = this.timeline[i];
442
- switch (event.type) {
443
- case "setTempo": {
444
- const durationTicks = event.ticks - prevTicks;
445
- totalTime += this.ticksToSecond(durationTicks, secondsPerBeat);
446
- secondsPerBeat = event.microsecondsPerBeat / 1000000;
447
- prevTicks = event.ticks;
448
- break;
449
- }
450
- case "endOfTrack":
451
- endOfTracks.push(event);
452
- }
453
- }
454
- let maxTicks = 0;
455
- for (let i = 0; i < endOfTracks.length; i++) {
456
- const event = endOfTracks[i];
457
- if (maxTicks < event.ticks)
458
- maxTicks = event.ticks;
444
+ if (totalTime < event.startTime)
445
+ totalTime = event.startTime;
459
446
  }
460
- const durationTicks = maxTicks - prevTicks;
461
- totalTime += this.ticksToSecond(durationTicks, secondsPerBeat);
462
447
  return totalTime;
463
448
  }
464
449
  currentTime() {
@@ -486,43 +471,8 @@ class MidyGM1 {
486
471
  const lfo = new OscillatorNode(audioContext, {
487
472
  frequency: 5,
488
473
  });
489
- const lfoGain = new GainNode(audioContext);
490
- lfo.connect(lfoGain);
491
474
  return {
492
475
  lfo,
493
- lfoGain,
494
- };
495
- }
496
- createReverbEffect(audioContext, options = {}) {
497
- const { decay = 0.8, preDecay = 0, } = options;
498
- const sampleRate = audioContext.sampleRate;
499
- const length = sampleRate * decay;
500
- const impulse = new AudioBuffer({
501
- numberOfChannels: 2,
502
- length,
503
- sampleRate,
504
- });
505
- const preDecayLength = Math.min(sampleRate * preDecay, length);
506
- for (let channel = 0; channel < impulse.numberOfChannels; channel++) {
507
- const channelData = impulse.getChannelData(channel);
508
- for (let i = 0; i < preDecayLength; i++) {
509
- channelData[i] = Math.random() * 2 - 1;
510
- }
511
- for (let i = preDecayLength; i < length; i++) {
512
- const attenuation = Math.exp(-(i - preDecayLength) / sampleRate / decay);
513
- channelData[i] = (Math.random() * 2 - 1) * attenuation;
514
- }
515
- }
516
- const convolverNode = new ConvolverNode(audioContext, {
517
- buffer: impulse,
518
- });
519
- const dryGain = new GainNode(audioContext);
520
- const wetGain = new GainNode(audioContext);
521
- convolverNode.connect(wetGain);
522
- return {
523
- convolverNode,
524
- dryGain,
525
- wetGain,
526
476
  };
527
477
  }
528
478
  connectNoteEffects(channel, gainNode) {
@@ -534,13 +484,17 @@ class MidyGM1 {
534
484
  centToHz(cent) {
535
485
  return 8.176 * Math.pow(2, cent / 1200);
536
486
  }
537
- async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
487
+ calcSemitoneOffset(channel) {
538
488
  const tuning = channel.coarseTuning + channel.fineTuning;
539
- const semitoneOffset = channel.pitchBend * channel.pitchBendRange + tuning;
540
- const playbackRate = noteInfo.playbackRate(noteNumber) *
541
- Math.pow(2, semitoneOffset / 12);
489
+ return channel.pitchBend * channel.pitchBendRange + tuning;
490
+ }
491
+ calcPlaybackRate(noteInfo, noteNumber, semitoneOffset) {
492
+ return noteInfo.playbackRate(noteNumber) * Math.pow(2, semitoneOffset / 12);
493
+ }
494
+ async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
542
495
  const bufferSource = await this.createNoteBufferNode(noteInfo, isSF3);
543
- bufferSource.playbackRate.value = playbackRate;
496
+ const semitoneOffset = this.calcSemitoneOffset(channel);
497
+ bufferSource.playbackRate.value = this.calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
544
498
  // volume envelope
545
499
  const gainNode = new GainNode(this.audioContext, {
546
500
  gain: 0,
@@ -559,12 +513,6 @@ class MidyGM1 {
559
513
  .exponentialRampToValueAtTime(attackVolume, volAttack)
560
514
  .setValueAtTime(attackVolume, volHold)
561
515
  .linearRampToValueAtTime(sustainVolume, volDecay);
562
- if (channel.modulation > 0) {
563
- const lfoGain = channel.modulationEffect.lfoGain;
564
- lfoGain.connect(bufferSource.detune);
565
- lfoGain.gain.cancelScheduledValues(startTime + channel.vibratoDelay);
566
- lfoGain.gain.setValueAtTime(channel.modulation, startTime + channel.vibratoDelay);
567
- }
568
516
  // filter envelope
569
517
  const maxFreq = this.audioContext.sampleRate / 2;
570
518
  const baseFreq = this.centToHz(noteInfo.initialFilterFc);
@@ -588,10 +536,23 @@ class MidyGM1 {
588
536
  .exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
589
537
  .setValueAtTime(adjustedPeekFreq, modHold)
590
538
  .linearRampToValueAtTime(adjustedSustainFreq, modDecay);
539
+ let lfoGain;
540
+ if (channel.modulation > 0) {
541
+ const vibratoDelay = startTime + channel.vibratoDelay;
542
+ const vibratoAttack = vibratoDelay + 0.1;
543
+ lfoGain = new GainNode(this.audioContext, {
544
+ gain: 0,
545
+ });
546
+ lfoGain.gain
547
+ .setValueAtTime(1e-6, vibratoDelay) // exponentialRampToValueAtTime() requires a non-zero value
548
+ .exponentialRampToValueAtTime(channel.modulation, vibratoAttack);
549
+ channel.modulationEffect.lfo.connect(lfoGain);
550
+ lfoGain.connect(bufferSource.detune);
551
+ }
591
552
  bufferSource.connect(filterNode);
592
553
  filterNode.connect(gainNode);
593
554
  bufferSource.start(startTime, noteInfo.start / noteInfo.sampleRate);
594
- return { bufferSource, gainNode, filterNode };
555
+ return { bufferSource, gainNode, filterNode, lfoGain };
595
556
  }
596
557
  async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
597
558
  const channel = this.channels[channelNumber];
@@ -604,16 +565,17 @@ class MidyGM1 {
604
565
  const noteInfo = soundFont.getInstrumentKey(bankNumber, channel.program, noteNumber);
605
566
  if (!noteInfo)
606
567
  return;
607
- const { bufferSource, gainNode, filterNode } = await this
568
+ const { bufferSource, gainNode, filterNode, lfoGain } = await this
608
569
  .createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3);
609
570
  this.connectNoteEffects(channel, gainNode);
610
571
  const scheduledNotes = channel.scheduledNotes;
611
572
  const scheduledNote = {
612
- gainNode,
613
- filterNode,
614
573
  bufferSource,
615
- noteNumber,
574
+ filterNode,
575
+ gainNode,
576
+ lfoGain,
616
577
  noteInfo,
578
+ noteNumber,
617
579
  startTime,
618
580
  };
619
581
  if (scheduledNotes.has(noteNumber)) {
@@ -640,7 +602,7 @@ class MidyGM1 {
640
602
  continue;
641
603
  if (targetNote.ending)
642
604
  continue;
643
- const { bufferSource, filterNode, gainNode, noteInfo } = targetNote;
605
+ const { bufferSource, filterNode, gainNode, lfoGain, noteInfo } = targetNote;
644
606
  const velocityRate = (velocity + 127) / 127;
645
607
  const volEndTime = stopTime + noteInfo.volRelease * velocityRate;
646
608
  gainNode.gain.cancelScheduledValues(stopTime);
@@ -662,6 +624,8 @@ class MidyGM1 {
662
624
  bufferSource.disconnect(0);
663
625
  filterNode.disconnect(0);
664
626
  gainNode.disconnect(0);
627
+ if (lfoGain)
628
+ lfoGain.disconnect(0);
665
629
  resolve();
666
630
  };
667
631
  bufferSource.stop(volEndTime);
@@ -672,28 +636,21 @@ class MidyGM1 {
672
636
  const now = this.audioContext.currentTime;
673
637
  return this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now);
674
638
  }
675
- releaseSustainPedal(channelNumber) {
676
- const now = this.audioContext.currentTime;
639
+ releaseSustainPedal(channelNumber, halfVelocity) {
640
+ const velocity = halfVelocity * 2;
677
641
  const channel = this.channels[channelNumber];
642
+ const promises = [];
678
643
  channel.sustainPedal = false;
679
644
  channel.scheduledNotes.forEach((scheduledNotes) => {
680
645
  scheduledNotes.forEach((scheduledNote) => {
681
646
  if (scheduledNote) {
682
- const { bufferSource, gainNode, filterNode, noteInfo } = scheduledNote;
683
- const volEndTime = now + noteInfo.volRelease;
684
- gainNode.gain.cancelScheduledValues(now);
685
- gainNode.gain.linearRampToValueAtTime(0, volEndTime);
686
- const maxFreq = this.audioContext.sampleRate / 2;
687
- const baseFreq = this.centToHz(noteInfo.initialFilterFc);
688
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
689
- const modEndTime = now + noteInfo.modRelease;
690
- filterNode.frequency
691
- .cancelScheduledValues(stopTime)
692
- .linearRampToValueAtTime(adjustedBaseFreq, modEndTime);
693
- bufferSource.stop(volEndTime);
647
+ const { noteNumber } = scheduledNote;
648
+ const promise = this.releaseNote(channelNumber, noteNumber, velocity);
649
+ promises.push(promise);
694
650
  }
695
651
  });
696
652
  });
653
+ return promises;
697
654
  }
698
655
  handleMIDIMessage(statusByte, data1, data2) {
699
656
  const channelNumber = statusByte & 0x0F;
@@ -703,46 +660,37 @@ class MidyGM1 {
703
660
  return this.releaseNote(channelNumber, data1, data2);
704
661
  case 0x90:
705
662
  return this.noteOn(channelNumber, data1, data2);
706
- case 0xA0:
707
- return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
708
663
  case 0xB0:
709
664
  return this.handleControlChange(channelNumber, data1, data2);
710
665
  case 0xC0:
711
666
  return this.handleProgramChange(channelNumber, data1);
712
- case 0xD0:
713
- return this.handleChannelPressure(channelNumber, data1);
714
667
  case 0xE0:
715
- return this.handlePitchBend(channelNumber, data1, data2);
668
+ return this.handlePitchBendMessage(channelNumber, data1, data2);
716
669
  default:
717
670
  console.warn(`Unsupported MIDI message: ${messageType.toString(16)}`);
718
671
  }
719
672
  }
720
- handlePolyphonicKeyPressure(channelNumber, noteNumber, pressure) {
721
- const now = this.audioContext.currentTime;
722
- const channel = this.channels[channelNumber];
723
- const scheduledNotes = channel.scheduledNotes.get(noteNumber);
724
- pressure /= 127;
725
- if (scheduledNotes) {
726
- scheduledNotes.forEach((scheduledNote) => {
727
- if (scheduledNote) {
728
- const { initialAttenuation } = scheduledNote.noteInfo;
729
- const gain = this.cbToRatio(-initialAttenuation) * pressure;
730
- scheduledNote.gainNode.gain.cancelScheduledValues(now);
731
- scheduledNote.gainNode.gain.setValueAtTime(gain, now);
732
- }
733
- });
734
- }
735
- }
736
673
  handleProgramChange(channelNumber, program) {
737
674
  const channel = this.channels[channelNumber];
738
675
  channel.program = program;
739
676
  }
740
- handleChannelPressure(channelNumber, pressure) {
741
- this.channels[channelNumber].channelPressure = pressure;
677
+ handlePitchBendMessage(channelNumber, lsb, msb) {
678
+ const pitchBend = msb * 128 + lsb;
679
+ this.handlePitchBend(channelNumber, pitchBend);
742
680
  }
743
- handlePitchBend(channelNumber, lsb, msb) {
744
- const pitchBend = (msb * 128 + lsb - 8192) / 8192;
745
- this.channels[channelNumber].pitchBend = pitchBend;
681
+ handlePitchBend(channelNumber, pitchBend) {
682
+ const now = this.audioContext.currentTime;
683
+ const channel = this.channels[channelNumber];
684
+ channel.pitchBend = (pitchBend - 8192) / 8192;
685
+ const semitoneOffset = this.calcSemitoneOffset(channel);
686
+ const activeNotes = this.getActiveNotes(channel);
687
+ activeNotes.forEach((activeNote) => {
688
+ const { bufferSource, noteInfo, noteNumber } = activeNote;
689
+ const playbackRate = calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
690
+ bufferSource.playbackRate
691
+ .cancelScheduledValues(now)
692
+ .setValueAtTime(playbackRate * pressure, now);
693
+ });
746
694
  }
747
695
  handleControlChange(channelNumber, controller, value) {
748
696
  switch (controller) {
@@ -775,13 +723,9 @@ class MidyGM1 {
775
723
  }
776
724
  }
777
725
  setModulation(channelNumber, modulation) {
778
- const now = this.audioContext.currentTime;
779
726
  const channel = this.channels[channelNumber];
780
- channel.modulation = (modulation * 100 / 127) *
781
- channel.modulationDepthRange;
782
- const lfoGain = channel.modulationEffect.lfoGain;
783
- lfoGain.gain.cancelScheduledValues(now);
784
- lfoGain.gain.setValueAtTime(channel.modulation, now);
727
+ channel.modulation = (modulation / 127) *
728
+ (channel.modulationDepthRange * 100);
785
729
  }
786
730
  setVolume(channelNumber, volume) {
787
731
  const channel = this.channels[channelNumber];
@@ -810,7 +754,7 @@ class MidyGM1 {
810
754
  const isOn = value >= 64;
811
755
  this.channels[channelNumber].sustainPedal = isOn;
812
756
  if (!isOn) {
813
- this.releaseSustainPedal(channelNumber);
757
+ this.releaseSustainPedal(channelNumber, value);
814
758
  }
815
759
  }
816
760
  setRPNMSB(channelNumber, value) {
@@ -912,13 +856,18 @@ class MidyGM1 {
912
856
  }
913
857
  }
914
858
  handleMasterVolumeSysEx(data) {
915
- const volume = (data[5] * 128 + data[4] - 8192) / 8192;
859
+ const volume = (data[5] * 128 + data[4]) / 16383;
916
860
  this.handleMasterVolume(volume);
917
861
  }
918
862
  handleMasterVolume(volume) {
919
- const now = this.audioContext.currentTime;
920
- this.masterGain.gain.cancelScheduledValues(now);
921
- this.masterGain.gain.setValueAtTime(volume * volume, now);
863
+ if (volume < 0 && 1 < volume) {
864
+ console.error("Master Volume is out of range");
865
+ }
866
+ else {
867
+ const now = this.audioContext.currentTime;
868
+ this.masterGain.gain.cancelScheduledValues(now);
869
+ this.masterGain.gain.setValueAtTime(volume * volume, now);
870
+ }
922
871
  }
923
872
  handleExclusiveMessage(data) {
924
873
  console.warn(`Unsupported Exclusive Message ${data}`);
@@ -951,7 +900,7 @@ Object.defineProperty(MidyGM1, "channelSettings", {
951
900
  configurable: true,
952
901
  writable: true,
953
902
  value: {
954
- volume: 1,
903
+ volume: 100 / 127,
955
904
  pan: 0,
956
905
  vibratoRate: 5,
957
906
  vibratoDepth: 0.5,
@@ -963,7 +912,7 @@ Object.defineProperty(MidyGM1, "channelSettings", {
963
912
  pitchBend: 0,
964
913
  fineTuning: 0,
965
914
  coarseTuning: 0,
966
- modulationDepthRange: 2,
915
+ modulationDepthRange: 0.5,
967
916
  }
968
917
  });
969
918
  Object.defineProperty(MidyGM1, "effectSettings", {
@@ -32,9 +32,16 @@ export class MidyGM2 {
32
32
  channelPressure: number;
33
33
  pitchBendRange: number;
34
34
  };
35
+ static controllerDestinationSettings: {
36
+ pitchControl: number;
37
+ filterCutoffControl: number;
38
+ amplitudeControl: number;
39
+ lfoPitchDepth: number;
40
+ lfoFilterDepth: number;
41
+ lfoAmplitudeDepth: number;
42
+ };
35
43
  constructor(audioContext: any);
36
44
  ticksPerBeat: number;
37
- secondsPerBeat: number;
38
45
  totalTime: number;
39
46
  reverbFactor: number;
40
47
  masterFineTuning: number;
@@ -58,56 +65,7 @@ export class MidyGM2 {
58
65
  notePromises: any[];
59
66
  audioContext: any;
60
67
  masterGain: any;
61
- channels: {
62
- scheduledNotes: Map<any, any>;
63
- sostenutoNotes: Map<any, any>;
64
- gainNode: any;
65
- pannerNode: any;
66
- modulationEffect: {
67
- lfo: any;
68
- lfoGain: any;
69
- };
70
- reverbEffect: {
71
- convolverNode: any;
72
- dryGain: any;
73
- wetGain: any;
74
- };
75
- chorusEffect: {
76
- lfo: any;
77
- lfoGain: any;
78
- delayNodes: any[];
79
- chorusGains: any[];
80
- };
81
- expression: number;
82
- modulation: number;
83
- sustainPedal: boolean;
84
- portamento: boolean;
85
- sostenutoPedal: boolean;
86
- softPedal: number;
87
- rpnMSB: number;
88
- rpnLSB: number;
89
- channelPressure: number;
90
- pitchBendRange: number;
91
- currentBufferSource: null;
92
- volume: number;
93
- pan: number;
94
- portamentoTime: number;
95
- reverb: number;
96
- chorus: number;
97
- vibratoRate: number;
98
- vibratoDepth: number;
99
- vibratoDelay: number;
100
- bank: number;
101
- bankMSB: number;
102
- bankLSB: number;
103
- dataMSB: number;
104
- dataLSB: number;
105
- program: number;
106
- pitchBend: number;
107
- fineTuning: number;
108
- coarseTuning: number;
109
- modulationDepthRange: number;
110
- }[];
68
+ channels: any[];
111
69
  initSoundFontTable(): any[];
112
70
  addSoundFont(soundFont: any): void;
113
71
  loadSoundFont(soundFontUrl: any): Promise<void>;
@@ -117,7 +75,6 @@ export class MidyGM2 {
117
75
  pannerNode: any;
118
76
  modulationEffect: {
119
77
  lfo: any;
120
- lfoGain: any;
121
78
  };
122
79
  reverbEffect: {
123
80
  convolverNode: any;
@@ -131,56 +88,7 @@ export class MidyGM2 {
131
88
  chorusGains: any[];
132
89
  };
133
90
  };
134
- createChannels(audioContext: any): {
135
- scheduledNotes: Map<any, any>;
136
- sostenutoNotes: Map<any, any>;
137
- gainNode: any;
138
- pannerNode: any;
139
- modulationEffect: {
140
- lfo: any;
141
- lfoGain: any;
142
- };
143
- reverbEffect: {
144
- convolverNode: any;
145
- dryGain: any;
146
- wetGain: any;
147
- };
148
- chorusEffect: {
149
- lfo: any;
150
- lfoGain: any;
151
- delayNodes: any[];
152
- chorusGains: any[];
153
- };
154
- expression: number;
155
- modulation: number;
156
- sustainPedal: boolean;
157
- portamento: boolean;
158
- sostenutoPedal: boolean;
159
- softPedal: number;
160
- rpnMSB: number;
161
- rpnLSB: number;
162
- channelPressure: number;
163
- pitchBendRange: number;
164
- currentBufferSource: null;
165
- volume: number;
166
- pan: number;
167
- portamentoTime: number;
168
- reverb: number;
169
- chorus: number;
170
- vibratoRate: number;
171
- vibratoDepth: number;
172
- vibratoDelay: number;
173
- bank: number;
174
- bankMSB: number;
175
- bankLSB: number;
176
- dataMSB: number;
177
- dataLSB: number;
178
- program: number;
179
- pitchBend: number;
180
- fineTuning: number;
181
- coarseTuning: number;
182
- modulationDepthRange: number;
183
- }[];
91
+ createChannels(audioContext: any): any[];
184
92
  createNoteBuffer(noteInfo: any, isSF3: any): Promise<any>;
185
93
  createNoteBufferNode(noteInfo: any, isSF3: any): Promise<any>;
186
94
  convertToFloat32Array(uint8Array: any): Float32Array;
@@ -205,7 +113,6 @@ export class MidyGM2 {
205
113
  getActiveChannelNotes(scheduledNotes: any): any;
206
114
  createModulationEffect(audioContext: any): {
207
115
  lfo: any;
208
- lfoGain: any;
209
116
  };
210
117
  createReverbEffect(audioContext: any, options?: {}): {
211
118
  convolverNode: any;
@@ -221,23 +128,26 @@ export class MidyGM2 {
221
128
  connectNoteEffects(channel: any, gainNode: any): void;
222
129
  cbToRatio(cb: any): number;
223
130
  centToHz(cent: any): number;
131
+ calcSemitoneOffset(channel: any): any;
132
+ calcPlaybackRate(noteInfo: any, noteNumber: any, semitoneOffset: any): number;
224
133
  createNoteAudioChain(channel: any, noteInfo: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<{
225
134
  bufferSource: any;
226
135
  gainNode: any;
227
136
  filterNode: any;
137
+ lfoGain: any;
228
138
  }>;
229
139
  calcBank(channel: any, channelNumber: any): any;
230
140
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
231
141
  noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
232
142
  scheduleNoteRelease(channelNumber: any, noteNumber: any, velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
233
143
  releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
234
- releaseSustainPedal(channelNumber: any): void;
235
- releaseSostenuto(channelNumber: any): void;
144
+ releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
145
+ releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
236
146
  handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
237
- handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
238
147
  handleProgramChange(channelNumber: any, program: any): void;
239
148
  handleChannelPressure(channelNumber: any, pressure: any): void;
240
- handlePitchBend(channelNumber: any, lsb: any, msb: any): void;
149
+ handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
150
+ handlePitchBend(channelNumber: any, pitchBend: any): void;
241
151
  handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
242
152
  setBankMSB(channelNumber: any, msb: any): void;
243
153
  setModulation(channelNumber: any, modulation: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.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;;;;OAiFC;IAED,gDAQC;IAED,kGA+CC;IAED,0EAGC;IAED,sIA2CC;IAED,0FAGC;IAED,8CAuBC;IAED,2CAYC;IAED,wFAqBC;IAED,sFAeC;IAED,4DAIC;IAED,+DAEC;IAED,8DAGC;IAED,mFAuDC;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,gDAEC;IAED,gDAEC;IAED,+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-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAMA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,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;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C,gBAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;;;;MAuBC;IAED,yCAcC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EAkDC;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,sCAKC;IAED,8EAEC;IAED;;;;;OAqFC;IAED,gDAQC;IAED,kGAgDC;IAED,0EAGC;IAED,sIA6CC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,wFAmBC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,0DAiBC;IAED,mFAuDC;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,gDAEC;IAED,gDAEC;IAED,+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,sCAQC;IAED,6CAGC;IAED,8CAMC;IAED,+CAGC;IAED,kDAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}