@marmooo/midy 0.1.1 → 0.1.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.
package/esm/midy.js CHANGED
@@ -82,7 +82,7 @@ export class Midy {
82
82
  writable: true,
83
83
  value: {
84
84
  time: this.getReverbTime(64),
85
- feedback: 0.25,
85
+ feedback: 0.8,
86
86
  }
87
87
  });
88
88
  Object.defineProperty(this, "chorus", {
@@ -224,8 +224,12 @@ export class Midy {
224
224
  this.audioContext = audioContext;
225
225
  this.options = { ...this.defaultOptions, ...options };
226
226
  this.masterGain = new GainNode(audioContext);
227
- this.masterGain.connect(audioContext.destination);
228
227
  this.channels = this.createChannels(audioContext);
228
+ this.reverbEffect = this.options.reverbAlgorithm(audioContext);
229
+ this.chorusEffect = this.createChorusEffect(audioContext);
230
+ this.chorusEffect.output.connect(this.masterGain);
231
+ this.reverbEffect.output.connect(this.masterGain);
232
+ this.masterGain.connect(audioContext.destination);
229
233
  this.GM2SystemOn();
230
234
  }
231
235
  initSoundFontTable() {
@@ -269,14 +273,11 @@ export class Midy {
269
273
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
270
274
  gainL.connect(merger, 0, 0);
271
275
  gainR.connect(merger, 0, 1);
272
- const reverbEffect = this.options.reverbAlgorithm(audioContext);
273
- const chorusEffect = this.createChorusEffect(audioContext);
276
+ merger.connect(this.masterGain);
274
277
  return {
275
278
  gainL,
276
279
  gainR,
277
280
  merger,
278
- reverbEffect,
279
- chorusEffect,
280
281
  };
281
282
  }
282
283
  createChannels(audioContext) {
@@ -692,7 +693,7 @@ export class Midy {
692
693
  }
693
694
  // https://hajim.rochester.edu/ece/sites/zduan/teaching/ece472/reading/Schroeder_1962.pdf
694
695
  // M.R.Schroeder, "Natural Sounding Artificial Reverberation", J.Audio Eng. Soc., vol.10, p.219, 1962
695
- createSchroederReverb(audioContext, combDelays, combFeedbacks, allpassDelays, allpassFeedbacks) {
696
+ createSchroederReverb(audioContext, combFeedbacks, combDelays, allpassFeedbacks, allpassDelays) {
696
697
  const input = new GainNode(audioContext);
697
698
  const output = new GainNode(audioContext);
698
699
  const mergerGain = new GainNode(audioContext);
@@ -751,21 +752,6 @@ export class Midy {
751
752
  feedbackGains,
752
753
  };
753
754
  }
754
- connectEffects(channel, gainNode) {
755
- gainNode.connect(channel.merger);
756
- channel.merger.connect(this.masterGain);
757
- if (0 < channel.reverbSendLevel) {
758
- channel.merger.connect(channel.reverbEffect.input);
759
- channel.reverbEffect.output.connect(this.masterGain);
760
- }
761
- if (0 < channel.chorusSendLevel) {
762
- channel.merger.connect(channel.chorusEffect.input);
763
- channel.reverbEffect.output.connect(this.masterGain);
764
- }
765
- if (0 < this.chorus.sendToReverb) {
766
- channel.chorusEffect.sendGain.connect(channel.reverbEffect.input);
767
- }
768
- }
769
755
  cbToRatio(cb) {
770
756
  return Math.pow(10, cb / 200);
771
757
  }
@@ -782,14 +768,10 @@ export class Midy {
782
768
  return instrumentKey.playbackRate(noteNumber) *
783
769
  Math.pow(2, semitoneOffset / 12);
784
770
  }
785
- setVolumeEnvelope(channel, note) {
786
- const { instrumentKey, startTime, velocity } = note;
771
+ setVolumeEnvelope(note) {
772
+ const { instrumentKey, startTime } = note;
787
773
  note.gainNode = new GainNode(this.audioContext, { gain: 0 });
788
- let volume = (velocity / 127) * channel.volume * channel.expression;
789
- if (volume === 0)
790
- volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
791
- const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation) *
792
- volume;
774
+ const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
793
775
  const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
794
776
  const volDelay = startTime + instrumentKey.volDelay;
795
777
  const volAttack = volDelay + instrumentKey.volAttack;
@@ -862,7 +844,7 @@ export class Midy {
862
844
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
863
845
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
864
846
  note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
865
- this.setVolumeEnvelope(channel, note);
847
+ this.setVolumeEnvelope(note);
866
848
  this.setFilterEnvelope(channel, note);
867
849
  if (channel.modulation > 0) {
868
850
  const delayModLFO = startTime + instrumentKey.delayModLFO;
@@ -902,7 +884,8 @@ export class Midy {
902
884
  if (!instrumentKey)
903
885
  return;
904
886
  const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
905
- this.connectEffects(channel, note.gainNode);
887
+ note.gainNode.connect(channel.gainL);
888
+ note.gainNode.connect(channel.gainR);
906
889
  if (channel.sostenutoPedal) {
907
890
  channel.sostenutoNotes.set(noteNumber, note);
908
891
  }
@@ -1062,13 +1045,13 @@ export class Midy {
1062
1045
  }
1063
1046
  }
1064
1047
  handlePitchBendMessage(channelNumber, lsb, msb) {
1065
- const pitchBend = msb * 128 + lsb;
1048
+ const pitchBend = msb * 128 + lsb - 8192;
1066
1049
  this.setPitchBend(channelNumber, pitchBend);
1067
1050
  }
1068
1051
  setPitchBend(channelNumber, pitchBend) {
1069
1052
  const channel = this.channels[channelNumber];
1070
1053
  const prevPitchBend = channel.pitchBend;
1071
- channel.pitchBend = (pitchBend - 8192) / 8192;
1054
+ channel.pitchBend = pitchBend / 8192;
1072
1055
  const detuneChange = (channel.pitchBend - prevPitchBend) *
1073
1056
  channel.pitchBendRange * 100;
1074
1057
  this.updateDetune(channel, detuneChange);
@@ -1214,20 +1197,30 @@ export class Midy {
1214
1197
  this.channels[channelNumber].portamento = value >= 64;
1215
1198
  }
1216
1199
  setReverbSendLevel(channelNumber, reverbSendLevel) {
1217
- const now = this.audioContext.currentTime;
1218
1200
  const channel = this.channels[channelNumber];
1219
- const reverbEffect = channel.reverbEffect;
1220
- channel.reverbSendLevel = reverbSendLevel / 127;
1221
- reverbEffect.output.gain.cancelScheduledValues(now);
1222
- reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
1201
+ const reverbEffect = this.reverbEffect;
1202
+ if (0 < reverbSendLevel) {
1203
+ const now = this.audioContext.currentTime;
1204
+ channel.reverbSendLevel = reverbSendLevel / 127;
1205
+ reverbEffect.output.gain.cancelScheduledValues(now);
1206
+ reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
1207
+ }
1208
+ else if (channel.reverbSendLevel !== 0) {
1209
+ channel.merger.disconnect(reverbEffect.input);
1210
+ }
1223
1211
  }
1224
1212
  setChorusSendLevel(channelNumber, chorusSendLevel) {
1225
- const now = this.audioContext.currentTime;
1226
1213
  const channel = this.channels[channelNumber];
1227
- const chorusEffect = channel.chorusEffect;
1228
- channel.chorusSendLevel = chorusSendLevel / 127;
1229
- chorusEffect.output.gain.cancelScheduledValues(now);
1230
- chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
1214
+ const chorusEffect = this.chorusEffect;
1215
+ if (0 < chorusSendLevel) {
1216
+ const now = this.audioContext.currentTime;
1217
+ channel.chorusSendLevel = chorusSendLevel / 127;
1218
+ chorusEffect.output.gain.cancelScheduledValues(now);
1219
+ chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
1220
+ }
1221
+ else if (channel.chorusSendLevel !== 0) {
1222
+ channel.merger.disconnect(chorusEffect.input);
1223
+ }
1231
1224
  }
1232
1225
  setSostenutoPedal(channelNumber, value) {
1233
1226
  const isOn = value >= 64;
@@ -1420,7 +1413,7 @@ export class Midy {
1420
1413
  channel.scheduledNotes.forEach((noteList) => {
1421
1414
  const activeNote = this.getActiveNote(noteList, now);
1422
1415
  if (activeNote) {
1423
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
1416
+ const notePromise = this.scheduleNoteRelease(channelNumber, activeNote.noteNumber, velocity, now, stopPedal);
1424
1417
  promises.push(notePromise);
1425
1418
  }
1426
1419
  });
@@ -1589,11 +1582,9 @@ export class Midy {
1589
1582
  }
1590
1583
  setReverbType(type) {
1591
1584
  this.reverb.time = this.getReverbTimeFromType(type);
1592
- this.reverb.feedback = (type === 8) ? 0.1 : 0.2;
1593
- const { audioContext, channels, options } = this;
1594
- for (let i = 0; i < channels.length; i++) {
1595
- channels[i].reverbEffect = options.reverbAlgorithm(audioContext);
1596
- }
1585
+ this.reverb.feedback = (type === 8) ? 0.9 : 0.8;
1586
+ const { audioContext, options } = this;
1587
+ this.reverbEffect = options.reverbAlgorithm(audioContext);
1597
1588
  }
1598
1589
  getReverbTimeFromType(type) {
1599
1590
  switch (type) {
@@ -1735,15 +1726,17 @@ export class Midy {
1735
1726
  return value * 0.00763;
1736
1727
  }
1737
1728
  setChorusSendToReverb(value) {
1738
- const now = this.audioContext.currentTime;
1739
1729
  const sendToReverb = this.getChorusSendToReverb(value);
1740
- this.chorus.sendToReverb = sendToReverb;
1741
- for (let i = 0; i < this.channels.length; i++) {
1742
- const chorusEffect = this.channels[i].chorusEffect;
1743
- chorusEffect.sendGain.gain
1730
+ if (0 < sendToReverb) {
1731
+ const now = this.audioContext.currentTime;
1732
+ this.chorus.sendToReverb = sendToReverb;
1733
+ this.chorusEffect.sendGain.gain
1744
1734
  .cancelScheduledValues(now)
1745
1735
  .setValueAtTime(sendToReverb, now);
1746
1736
  }
1737
+ else if (this.chorus.sendToReverb !== 0) {
1738
+ this.chorusEffect.sendGain.disconnect(this.reverbEffect.input);
1739
+ }
1747
1740
  }
1748
1741
  getChorusSendToReverb(value) {
1749
1742
  return value * 0.00787;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marmooo/midy",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A MIDI player/synthesizer written in JavaScript that supports GM-Lite/GM1 and SF2/SF3.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -72,12 +72,11 @@ export class MidyGM1 {
72
72
  currentTime(): number;
73
73
  getActiveNotes(channel: any, time: any): Map<any, any>;
74
74
  getActiveNote(noteList: any, time: any): any;
75
- connectEffects(channel: any, gainNode: any): void;
76
75
  cbToRatio(cb: any): number;
77
76
  centToHz(cent: any): number;
78
77
  calcSemitoneOffset(channel: any): any;
79
78
  calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
80
- setVolumeEnvelope(channel: any, note: any): void;
79
+ setVolumeEnvelope(note: any): void;
81
80
  setFilterEnvelope(channel: any, note: any): void;
82
81
  startModulation(channel: any, note: any, time: any): void;
83
82
  createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqBA;IAmBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA9CD,qBAAmB;IACnB,kBAAc;IACd,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;IAyBhB,kBAAgC;IAChC,gBAA4C;IAE5C,gBAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAcC;IAED,yCAUC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA8DC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,kDAGC;IAED,2BAEC;IAED,4BAEC;IAED,sCAGC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHA6BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIA8CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,mFA+BC;IAED,qCAcC;IAED,yDAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAUC;IAED,kDAKC;IAED,iEAOC;IAED,8CAKC;IAED,yDAMC;IAED,gDAKC;IAED,6DAMC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAnjCD;IAOE,gFAKC;IAXD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
1
+ {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqBA;IAmBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA9CD,qBAAmB;IACnB,kBAAc;IACd,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;IAyBhB,kBAAgC;IAChC,gBAA4C;IAC5C,gBAAiD;IAKnD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA8DC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,4BAEC;IAED,sCAGC;IAED,mFAGC;IAED,mCAcC;IACD,iDAiCC;IAED,0DAmBC;IAED,wHA6BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIA8CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,mFA+BC;IAED,qCAcC;IAED,yDAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAUC;IAED,kDAKC;IAED,iEAOC;IAED,8CAKC;IAED,yDAMC;IAED,gDAKC;IAED,6DAMC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AA3iCD;IAOE,gFAKC;IAXD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
@@ -147,8 +147,8 @@ class MidyGM1 {
147
147
  });
148
148
  this.audioContext = audioContext;
149
149
  this.masterGain = new GainNode(audioContext);
150
- this.masterGain.connect(audioContext.destination);
151
150
  this.channels = this.createChannels(audioContext);
151
+ this.masterGain.connect(audioContext.destination);
152
152
  this.GM1SystemOn();
153
153
  }
154
154
  initSoundFontTable() {
@@ -192,6 +192,7 @@ class MidyGM1 {
192
192
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
193
193
  gainL.connect(merger, 0, 0);
194
194
  gainR.connect(merger, 0, 1);
195
+ merger.connect(this.masterGain);
195
196
  return {
196
197
  gainL,
197
198
  gainR,
@@ -494,10 +495,6 @@ class MidyGM1 {
494
495
  }
495
496
  return noteList[0];
496
497
  }
497
- connectEffects(channel, gainNode) {
498
- gainNode.connect(channel.merger);
499
- merger.connect(this.masterGain);
500
- }
501
498
  cbToRatio(cb) {
502
499
  return Math.pow(10, cb / 200);
503
500
  }
@@ -512,14 +509,10 @@ class MidyGM1 {
512
509
  return instrumentKey.playbackRate(noteNumber) *
513
510
  Math.pow(2, semitoneOffset / 12);
514
511
  }
515
- setVolumeEnvelope(channel, note) {
516
- const { instrumentKey, startTime, velocity } = note;
512
+ setVolumeEnvelope(note) {
513
+ const { instrumentKey, startTime } = note;
517
514
  note.gainNode = new GainNode(this.audioContext, { gain: 0 });
518
- let volume = (velocity / 127) * channel.volume * channel.expression;
519
- if (volume === 0)
520
- volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
521
- const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation) *
522
- volume;
515
+ const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
523
516
  const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
524
517
  const volDelay = startTime + instrumentKey.volDelay;
525
518
  const volAttack = volDelay + instrumentKey.volAttack;
@@ -579,7 +572,7 @@ class MidyGM1 {
579
572
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
580
573
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
581
574
  note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
582
- this.setVolumeEnvelope(channel, note);
575
+ this.setVolumeEnvelope(note);
583
576
  this.setFilterEnvelope(channel, note);
584
577
  if (channel.modulation > 0) {
585
578
  const delayModLFO = startTime + instrumentKey.delayModLFO;
@@ -602,7 +595,8 @@ class MidyGM1 {
602
595
  if (!instrumentKey)
603
596
  return;
604
597
  const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
605
- this.connectEffects(channel, note.gainNode);
598
+ note.gainNode.connect(channel.gainL);
599
+ note.gainNode.connect(channel.gainR);
606
600
  const scheduledNotes = channel.scheduledNotes;
607
601
  if (scheduledNotes.has(noteNumber)) {
608
602
  scheduledNotes.get(noteNumber).push(note);
@@ -705,13 +699,13 @@ class MidyGM1 {
705
699
  channel.program = program;
706
700
  }
707
701
  handlePitchBendMessage(channelNumber, lsb, msb) {
708
- const pitchBend = msb * 128 + lsb;
702
+ const pitchBend = msb * 128 + lsb - 8192;
709
703
  this.setPitchBend(channelNumber, pitchBend);
710
704
  }
711
705
  setPitchBend(channelNumber, pitchBend) {
712
706
  const channel = this.channels[channelNumber];
713
707
  const prevPitchBend = channel.pitchBend;
714
- channel.pitchBend = (pitchBend - 8192) / 8192;
708
+ channel.pitchBend = pitchBend / 8192;
715
709
  const detuneChange = (channel.pitchBend - prevPitchBend) *
716
710
  channel.pitchBendRange * 100;
717
711
  this.updateDetune(channel, detuneChange);
@@ -939,7 +933,7 @@ class MidyGM1 {
939
933
  channel.scheduledNotes.forEach((noteList) => {
940
934
  const activeNote = this.getActiveNote(noteList, now);
941
935
  if (activeNote) {
942
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
936
+ const notePromise = this.scheduleNoteRelease(channelNumber, activeNote.noteNumber, velocity, now, stopPedal);
943
937
  promises.push(notePromise);
944
938
  }
945
939
  });
@@ -90,6 +90,19 @@ export class MidyGM2 {
90
90
  };
91
91
  masterGain: any;
92
92
  channels: any[];
93
+ reverbEffect: {
94
+ input: any;
95
+ output: any;
96
+ };
97
+ chorusEffect: {
98
+ input: any;
99
+ output: any;
100
+ sendGain: any;
101
+ lfo: any;
102
+ lfoGain: any;
103
+ delayNodes: any[];
104
+ feedbackGains: any[];
105
+ };
93
106
  initSoundFontTable(): any[];
94
107
  addSoundFont(soundFont: any): void;
95
108
  loadSoundFont(soundFontUrl: any): Promise<void>;
@@ -98,19 +111,6 @@ export class MidyGM2 {
98
111
  gainL: any;
99
112
  gainR: any;
100
113
  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
114
  };
115
115
  createChannels(audioContext: any): any[];
116
116
  createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
@@ -144,7 +144,7 @@ export class MidyGM2 {
144
144
  createCombFilter(audioContext: any, input: any, delay: any, feedback: any): any;
145
145
  createAllpassFilter(audioContext: any, input: any, delay: any, feedback: any): any;
146
146
  generateDistributedArray(center: any, count: any, varianceRatio?: number, randomness?: number): any[];
147
- createSchroederReverb(audioContext: any, combDelays: any, combFeedbacks: any, allpassDelays: any, allpassFeedbacks: any): {
147
+ createSchroederReverb(audioContext: any, combFeedbacks: any, combDelays: any, allpassFeedbacks: any, allpassDelays: any): {
148
148
  input: any;
149
149
  output: any;
150
150
  };
@@ -157,12 +157,11 @@ export class MidyGM2 {
157
157
  delayNodes: any[];
158
158
  feedbackGains: any[];
159
159
  };
160
- connectEffects(channel: any, gainNode: any): void;
161
160
  cbToRatio(cb: any): number;
162
161
  centToHz(cent: any): number;
163
162
  calcSemitoneOffset(channel: any): any;
164
163
  calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
165
- setVolumeEnvelope(channel: any, note: any): void;
164
+ setVolumeEnvelope(note: any): void;
166
165
  setFilterEnvelope(channel: any, note: any): void;
167
166
  startModulation(channel: any, note: any, time: any): void;
168
167
  createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
@@ -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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"}
@@ -85,7 +85,7 @@ class MidyGM2 {
85
85
  writable: true,
86
86
  value: {
87
87
  time: this.getReverbTime(64),
88
- feedback: 0.25,
88
+ feedback: 0.8,
89
89
  }
90
90
  });
91
91
  Object.defineProperty(this, "chorus", {
@@ -227,8 +227,12 @@ class MidyGM2 {
227
227
  this.audioContext = audioContext;
228
228
  this.options = { ...this.defaultOptions, ...options };
229
229
  this.masterGain = new GainNode(audioContext);
230
- this.masterGain.connect(audioContext.destination);
231
230
  this.channels = this.createChannels(audioContext);
231
+ this.reverbEffect = this.options.reverbAlgorithm(audioContext);
232
+ this.chorusEffect = this.createChorusEffect(audioContext);
233
+ this.chorusEffect.output.connect(this.masterGain);
234
+ this.reverbEffect.output.connect(this.masterGain);
235
+ this.masterGain.connect(audioContext.destination);
232
236
  this.GM2SystemOn();
233
237
  }
234
238
  initSoundFontTable() {
@@ -272,14 +276,11 @@ class MidyGM2 {
272
276
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
273
277
  gainL.connect(merger, 0, 0);
274
278
  gainR.connect(merger, 0, 1);
275
- const reverbEffect = this.options.reverbAlgorithm(audioContext);
276
- const chorusEffect = this.createChorusEffect(audioContext);
279
+ merger.connect(this.masterGain);
277
280
  return {
278
281
  gainL,
279
282
  gainR,
280
283
  merger,
281
- reverbEffect,
282
- chorusEffect,
283
284
  };
284
285
  }
285
286
  createChannels(audioContext) {
@@ -689,7 +690,7 @@ class MidyGM2 {
689
690
  }
690
691
  // https://hajim.rochester.edu/ece/sites/zduan/teaching/ece472/reading/Schroeder_1962.pdf
691
692
  // M.R.Schroeder, "Natural Sounding Artificial Reverberation", J.Audio Eng. Soc., vol.10, p.219, 1962
692
- createSchroederReverb(audioContext, combDelays, combFeedbacks, allpassDelays, allpassFeedbacks) {
693
+ createSchroederReverb(audioContext, combFeedbacks, combDelays, allpassFeedbacks, allpassDelays) {
693
694
  const input = new GainNode(audioContext);
694
695
  const output = new GainNode(audioContext);
695
696
  const mergerGain = new GainNode(audioContext);
@@ -748,21 +749,6 @@ class MidyGM2 {
748
749
  feedbackGains,
749
750
  };
750
751
  }
751
- connectEffects(channel, gainNode) {
752
- gainNode.connect(channel.merger);
753
- channel.merger.connect(this.masterGain);
754
- if (0 < channel.reverbSendLevel) {
755
- channel.merger.connect(channel.reverbEffect.input);
756
- channel.reverbEffect.output.connect(this.masterGain);
757
- }
758
- if (0 < channel.chorusSendLevel) {
759
- channel.merger.connect(channel.chorusEffect.input);
760
- channel.reverbEffect.output.connect(this.masterGain);
761
- }
762
- if (0 < this.chorus.sendToReverb) {
763
- channel.chorusEffect.sendGain.connect(channel.reverbEffect.input);
764
- }
765
- }
766
752
  cbToRatio(cb) {
767
753
  return Math.pow(10, cb / 200);
768
754
  }
@@ -779,14 +765,10 @@ class MidyGM2 {
779
765
  return instrumentKey.playbackRate(noteNumber) *
780
766
  Math.pow(2, semitoneOffset / 12);
781
767
  }
782
- setVolumeEnvelope(channel, note) {
783
- const { instrumentKey, startTime, velocity } = note;
768
+ setVolumeEnvelope(note) {
769
+ const { instrumentKey, startTime } = note;
784
770
  note.gainNode = new GainNode(this.audioContext, { gain: 0 });
785
- let volume = (velocity / 127) * channel.volume * channel.expression;
786
- if (volume === 0)
787
- volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
788
- const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation) *
789
- volume;
771
+ const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
790
772
  const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
791
773
  const volDelay = startTime + instrumentKey.volDelay;
792
774
  const volAttack = volDelay + instrumentKey.volAttack;
@@ -846,7 +828,7 @@ class MidyGM2 {
846
828
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
847
829
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
848
830
  note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
849
- this.setVolumeEnvelope(channel, note);
831
+ this.setVolumeEnvelope(note);
850
832
  this.setFilterEnvelope(channel, note);
851
833
  if (channel.modulation > 0) {
852
834
  const delayModLFO = startTime + instrumentKey.delayModLFO;
@@ -882,7 +864,8 @@ class MidyGM2 {
882
864
  if (!instrumentKey)
883
865
  return;
884
866
  const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
885
- this.connectEffects(channel, note.gainNode);
867
+ note.gainNode.connect(channel.gainL);
868
+ note.gainNode.connect(channel.gainR);
886
869
  if (channel.sostenutoPedal) {
887
870
  channel.sostenutoNotes.set(noteNumber, note);
888
871
  }
@@ -1025,13 +1008,13 @@ class MidyGM2 {
1025
1008
  }
1026
1009
  }
1027
1010
  handlePitchBendMessage(channelNumber, lsb, msb) {
1028
- const pitchBend = msb * 128 + lsb;
1011
+ const pitchBend = msb * 128 + lsb - 8192;
1029
1012
  this.setPitchBend(channelNumber, pitchBend);
1030
1013
  }
1031
1014
  setPitchBend(channelNumber, pitchBend) {
1032
1015
  const channel = this.channels[channelNumber];
1033
1016
  const prevPitchBend = channel.pitchBend;
1034
- channel.pitchBend = (pitchBend - 8192) / 8192;
1017
+ channel.pitchBend = pitchBend / 8192;
1035
1018
  const detuneChange = (channel.pitchBend - prevPitchBend) *
1036
1019
  channel.pitchBendRange * 100;
1037
1020
  this.updateDetune(channel, detuneChange);
@@ -1166,20 +1149,30 @@ class MidyGM2 {
1166
1149
  this.channels[channelNumber].portamento = value >= 64;
1167
1150
  }
1168
1151
  setReverbSendLevel(channelNumber, reverbSendLevel) {
1169
- const now = this.audioContext.currentTime;
1170
1152
  const channel = this.channels[channelNumber];
1171
- const reverbEffect = channel.reverbEffect;
1172
- channel.reverbSendLevel = reverbSendLevel / 127;
1173
- reverbEffect.output.gain.cancelScheduledValues(now);
1174
- reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
1153
+ const reverbEffect = this.reverbEffect;
1154
+ if (0 < reverbSendLevel) {
1155
+ const now = this.audioContext.currentTime;
1156
+ channel.reverbSendLevel = reverbSendLevel / 127;
1157
+ reverbEffect.output.gain.cancelScheduledValues(now);
1158
+ reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
1159
+ }
1160
+ else if (channel.reverbSendLevel !== 0) {
1161
+ channel.merger.disconnect(reverbEffect.input);
1162
+ }
1175
1163
  }
1176
1164
  setChorusSendLevel(channelNumber, chorusSendLevel) {
1177
- const now = this.audioContext.currentTime;
1178
1165
  const channel = this.channels[channelNumber];
1179
- const chorusEffect = channel.chorusEffect;
1180
- channel.chorusSendLevel = chorusSendLevel / 127;
1181
- chorusEffect.output.gain.cancelScheduledValues(now);
1182
- chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
1166
+ const chorusEffect = this.chorusEffect;
1167
+ if (0 < chorusSendLevel) {
1168
+ const now = this.audioContext.currentTime;
1169
+ channel.chorusSendLevel = chorusSendLevel / 127;
1170
+ chorusEffect.output.gain.cancelScheduledValues(now);
1171
+ chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
1172
+ }
1173
+ else if (channel.chorusSendLevel !== 0) {
1174
+ channel.merger.disconnect(chorusEffect.input);
1175
+ }
1183
1176
  }
1184
1177
  setSostenutoPedal(channelNumber, value) {
1185
1178
  const isOn = value >= 64;
@@ -1344,7 +1337,7 @@ class MidyGM2 {
1344
1337
  channel.scheduledNotes.forEach((noteList) => {
1345
1338
  const activeNote = this.getActiveNote(noteList, now);
1346
1339
  if (activeNote) {
1347
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
1340
+ const notePromise = this.scheduleNoteRelease(channelNumber, activeNote.noteNumber, velocity, now, stopPedal);
1348
1341
  promises.push(notePromise);
1349
1342
  }
1350
1343
  });
@@ -1513,11 +1506,9 @@ class MidyGM2 {
1513
1506
  }
1514
1507
  setReverbType(type) {
1515
1508
  this.reverb.time = this.getReverbTimeFromType(type);
1516
- this.reverb.feedback = (type === 8) ? 0.1 : 0.2;
1517
- const { audioContext, channels, options } = this;
1518
- for (let i = 0; i < channels.length; i++) {
1519
- channels[i].reverbEffect = options.reverbAlgorithm(audioContext);
1520
- }
1509
+ this.reverb.feedback = (type === 8) ? 0.9 : 0.8;
1510
+ const { audioContext, options } = this;
1511
+ this.reverbEffect = options.reverbAlgorithm(audioContext);
1521
1512
  }
1522
1513
  getReverbTimeFromType(type) {
1523
1514
  switch (type) {
@@ -1659,15 +1650,17 @@ class MidyGM2 {
1659
1650
  return value * 0.00763;
1660
1651
  }
1661
1652
  setChorusSendToReverb(value) {
1662
- const now = this.audioContext.currentTime;
1663
1653
  const sendToReverb = this.getChorusSendToReverb(value);
1664
- this.chorus.sendToReverb = sendToReverb;
1665
- for (let i = 0; i < this.channels.length; i++) {
1666
- const chorusEffect = this.channels[i].chorusEffect;
1667
- chorusEffect.sendGain.gain
1654
+ if (0 < sendToReverb) {
1655
+ const now = this.audioContext.currentTime;
1656
+ this.chorus.sendToReverb = sendToReverb;
1657
+ this.chorusEffect.sendGain.gain
1668
1658
  .cancelScheduledValues(now)
1669
1659
  .setValueAtTime(sendToReverb, now);
1670
1660
  }
1661
+ else if (this.chorus.sendToReverb !== 0) {
1662
+ this.chorusEffect.sendGain.disconnect(this.reverbEffect.input);
1663
+ }
1671
1664
  }
1672
1665
  getChorusSendToReverb(value) {
1673
1666
  return value * 0.00787;
@@ -70,12 +70,11 @@ export class MidyGMLite {
70
70
  currentTime(): number;
71
71
  getActiveNotes(channel: any, time: any): Map<any, any>;
72
72
  getActiveNote(noteList: any, time: any): any;
73
- connectEffects(channel: any, gainNode: any): void;
74
73
  cbToRatio(cb: any): number;
75
74
  centToHz(cent: any): number;
76
75
  calcSemitoneOffset(channel: any): number;
77
76
  calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
78
- setVolumeEnvelope(channel: any, note: any): void;
77
+ setVolumeEnvelope(note: any): void;
79
78
  setFilterEnvelope(channel: any, note: any): void;
80
79
  startModulation(channel: any, note: any, time: any): void;
81
80
  createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAqBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA5CD,qBAAmB;IACnB,kBAAc;IACd,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;IAuBhB,kBAAgC;IAChC,gBAA4C;IAE5C,gBAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAcC;IAED,yCAUC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA8DC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,kDAGC;IAED,2BAEC;IAED,4BAEC;IAED,yCAEC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHA6BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIA8CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,mFA+BC;IAED,qCAcC;IAED,yDAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAUC;IAED,kDAKC;IAED,iEAOC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAn/BD;IAOE,gFAKC;IAXD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
1
+ {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAqBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA5CD,qBAAmB;IACnB,kBAAc;IACd,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;IAuBhB,kBAAgC;IAChC,gBAA4C;IAC5C,gBAAiD;IAKnD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA8DC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,4BAEC;IAED,yCAEC;IAED,mFAGC;IAED,mCAcC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHA6BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIA8CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,mFA+BC;IAED,qCAcC;IAED,yDAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAUC;IAED,kDAKC;IAED,iEAOC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AA5+BD;IAOE,gFAKC;IAXD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}