@marmooo/midy 0.4.3 → 0.4.5

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.
@@ -12,6 +12,7 @@ export class MidyGM1 extends EventTarget {
12
12
  coarseTuning: number;
13
13
  };
14
14
  constructor(audioContext: any);
15
+ perceptualSmoothingTime: number;
15
16
  mode: string;
16
17
  numChannels: number;
17
18
  ticksPerBeat: number;
@@ -55,6 +56,7 @@ export class MidyGM1 extends EventTarget {
55
56
  freqModLFO: (_channel: any, note: any, scheduleTime: any) => void;
56
57
  delayVibLFO: (_channel: any, _note: any, _scheduleTime: any) => void;
57
58
  freqVibLFO: (_channel: any, _note: any, _scheduleTime: any) => void;
59
+ detune: (channel: any, note: any, scheduleTime: any) => void;
58
60
  };
59
61
  controlChangeHandlers: any[];
60
62
  channels: any[];
@@ -92,6 +94,7 @@ export class MidyGM1 extends EventTarget {
92
94
  pause(): Promise<void>;
93
95
  resume(): Promise<void>;
94
96
  seekTo(second: any): void;
97
+ tempoChange(tempo: any): void;
95
98
  calcTotalTime(): number;
96
99
  currentTime(): number;
97
100
  processScheduledNotes(channel: any, callback: any): Promise<void>;
@@ -101,8 +104,9 @@ export class MidyGM1 extends EventTarget {
101
104
  centToHz(cent: any): number;
102
105
  calcChannelDetune(channel: any): any;
103
106
  updateChannelDetune(channel: any, scheduleTime: any): void;
104
- updateDetune(channel: any, note: any, scheduleTime: any): void;
107
+ calcNoteDetune(channel: any, note: any): any;
105
108
  setVolumeEnvelope(note: any, scheduleTime: any): void;
109
+ setDetune(channel: any, note: any, scheduleTime: any): void;
106
110
  setPitchEnvelope(note: any, scheduleTime: any): void;
107
111
  clampCutoffFrequency(frequency: any): number;
108
112
  setFilterEnvelope(note: any, scheduleTime: any): void;
@@ -140,20 +144,21 @@ export class MidyGM1 extends EventTarget {
140
144
  freqModLFO: (_channel: any, note: any, scheduleTime: any) => void;
141
145
  delayVibLFO: (_channel: any, _note: any, _scheduleTime: any) => void;
142
146
  freqVibLFO: (_channel: any, _note: any, _scheduleTime: any) => void;
147
+ detune: (channel: any, note: any, scheduleTime: any) => void;
143
148
  };
144
149
  getControllerState(channel: any, noteNumber: any, velocity: any): Float32Array<any>;
145
150
  applyVoiceParams(channel: any, controllerType: any, scheduleTime: any): void;
146
151
  createControlChangeHandlers(): any[];
147
152
  setControlChange(channelNumber: any, controllerType: any, value: any, scheduleTime: any): void;
148
153
  updateModulation(channel: any, scheduleTime: any): void;
149
- setModulationDepth(channelNumber: any, modulation: any, scheduleTime: any): void;
150
- setVolume(channelNumber: any, volume: any, scheduleTime: any): void;
154
+ setModulationDepth(channelNumber: any, value: any, scheduleTime: any): void;
155
+ setVolume(channelNumber: any, value: any, scheduleTime: any): void;
151
156
  panToGain(pan: any): {
152
157
  gainLeft: number;
153
158
  gainRight: number;
154
159
  };
155
- setPan(channelNumber: any, pan: any, scheduleTime: any): void;
156
- setExpression(channelNumber: any, expression: any, scheduleTime: any): void;
160
+ setPan(channelNumber: any, value: any, scheduleTime: any): void;
161
+ setExpression(channelNumber: any, value: any, scheduleTime: any): void;
157
162
  dataEntryLSB(channelNumber: any, value: any, scheduleTime: any): void;
158
163
  updateChannelVolume(channel: any, scheduleTime: any): void;
159
164
  setSustainPedal(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":"AAuGA;IA+BE;;;;;;;;;;;MAWE;IAEF,+BAgBC;IA3DD,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,iCAEG;IACH,cAAU;IACV,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,8DAeC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDASC;IAED,4DASC;IAED,gEAsDC;IAED,mCASC;IAED,uBAUC;IAED,yDAqCC;IAED,2BA0EC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAQC;IAED,uBAMC;IAED,sBAIC;IAED,uBAMC;IAED,wBAIC;IAED,0BAKC;IAED,wBAYC;IAED,sBAIC;IAED,kEAWC;IAED,kFAYC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDA6BC;IAED,kEAqBC;IAED,4GAkCC;IAED,uEAyCC;IAED,0EAiBC;IAED,oEASC;IAED,0FAwBC;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,qCAUC;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":"AAuGA;IAoCE;;;;;;;;;;;MAWE;IAEF,+BAgBC;IA5DD,gCAAgC;IAChC,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,iCAEG;IACH,cAAU;IACV,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,8DAeC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDASC;IAED,4DASC;IAED,gEAsDC;IAED,mCASC;IAED,uBAUC;IAED,yDAqCC;IAED,2BA0EC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAQC;IAED,uBAMC;IAED,sBAIC;IAED,uBAMC;IAED,wBAIC;IAED,0BAKC;IAED,8BAMC;IAED,wBAYC;IAED,sBAIC;IAED,kEAWC;IAED,kFAYC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAIC;IAED,6CAEC;IAED,sDAeC;IAED,4DASC;IAED,qDAkBC;IAED,6CAIC;IAED,sDA6BC;IAED,kEAqBC;IAED,4GAkCC;IAED,uEAyCC;IAED,0EAiBC;IAED,oEASC;IAED,0FAwBC;IAED,gCASC;IAED,iEAwBC;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;;;;;;;;;;;;MAoCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDAUC;IAED,4EAKC;IAED,mEAKC;IAED;;;MAMC;IAED,gEAKC;IAED,uEAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,2DAMC;IAED,uDAoBC;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,qCAUC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
@@ -164,6 +164,16 @@ const releaseCurve = 1 / (-Math.log(cbToRatio(-600)));
164
164
  class MidyGM1 extends EventTarget {
165
165
  constructor(audioContext) {
166
166
  super();
167
+ // https://pmc.ncbi.nlm.nih.gov/articles/PMC4191557/
168
+ // https://pubmed.ncbi.nlm.nih.gov/12488797/
169
+ // Gap detection studies indicate humans detect temporal discontinuities
170
+ // around 2–3 ms. Smoothing over ~4 ms is perceived as continuous.
171
+ Object.defineProperty(this, "perceptualSmoothingTime", {
172
+ enumerable: true,
173
+ configurable: true,
174
+ writable: true,
175
+ value: 0.004
176
+ });
167
177
  Object.defineProperty(this, "mode", {
168
178
  enumerable: true,
169
179
  configurable: true,
@@ -542,8 +552,8 @@ class MidyGM1 extends EventTarget {
542
552
  this.voiceCache.clear();
543
553
  this.realtimeVoiceCache.clear();
544
554
  const channels = this.channels;
545
- for (let i = 0; i < channels.length; i++) {
546
- channels[i].scheduledNotes = [];
555
+ for (let ch = 0; ch < channels.length; ch++) {
556
+ channels[ch].scheduledNotes = [];
547
557
  this.resetChannelStates(i);
548
558
  }
549
559
  }
@@ -734,8 +744,8 @@ class MidyGM1 extends EventTarget {
734
744
  }
735
745
  stopNotes(velocity, force, scheduleTime) {
736
746
  const channels = this.channels;
737
- for (let i = 0; i < channels.length; i++) {
738
- this.stopChannelNotes(i, velocity, force, scheduleTime);
747
+ for (let ch = 0; ch < channels.length; ch++) {
748
+ this.stopChannelNotes(ch, velocity, force, scheduleTime);
739
749
  }
740
750
  const stopPromise = Promise.all(this.notePromises);
741
751
  this.notePromises = [];
@@ -776,6 +786,13 @@ class MidyGM1 extends EventTarget {
776
786
  this.isSeeking = true;
777
787
  }
778
788
  }
789
+ tempoChange(tempo) {
790
+ const timeScale = this.tempo / tempo;
791
+ this.resumeTime = this.resumeTime * timeScale;
792
+ this.tempo = tempo;
793
+ this.totalTime = this.calcTotalTime();
794
+ this.seekTo(this.currentTime() * timeScale);
795
+ }
779
796
  calcTotalTime() {
780
797
  const totalTimeEventTypes = this.totalTimeEventTypes;
781
798
  const timeline = this.timeline;
@@ -845,13 +862,11 @@ class MidyGM1 extends EventTarget {
845
862
  }
846
863
  updateChannelDetune(channel, scheduleTime) {
847
864
  this.processScheduledNotes(channel, (note) => {
848
- this.updateDetune(channel, note, scheduleTime);
865
+ this.setDetune(channel, note, scheduleTime);
849
866
  });
850
867
  }
851
- updateDetune(channel, note, scheduleTime) {
852
- note.bufferSource.detune
853
- .cancelScheduledValues(scheduleTime)
854
- .setValueAtTime(channel.detune, scheduleTime);
868
+ calcNoteDetune(channel, note) {
869
+ return channel.detune + note.voiceParams.detune;
855
870
  }
856
871
  setVolumeEnvelope(note, scheduleTime) {
857
872
  const { voiceParams, startTime } = note;
@@ -864,30 +879,38 @@ class MidyGM1 extends EventTarget {
864
879
  note.volumeEnvelopeNode.gain
865
880
  .cancelScheduledValues(scheduleTime)
866
881
  .setValueAtTime(0, startTime)
867
- .setValueAtTime(0, volDelay)
868
- .linearRampToValueAtTime(attackVolume, volAttack)
882
+ .setValueAtTime(1e-6, volDelay)
883
+ .exponentialRampToValueAtTime(attackVolume, volAttack)
869
884
  .setValueAtTime(attackVolume, volHold)
870
885
  .setTargetAtTime(sustainVolume, volHold, decayDuration * decayCurve);
871
886
  }
887
+ setDetune(channel, note, scheduleTime) {
888
+ const detune = this.calcNoteDetune(channel, note);
889
+ note.bufferSource.detune
890
+ .cancelScheduledValues(scheduleTime)
891
+ .setValueAtTime(detune, scheduleTime);
892
+ const timeConstant = this.perceptualSmoothingTime / 5; // 99.3% (5 * tau)
893
+ note.bufferSource.detune
894
+ .cancelAndHoldAtTime(scheduleTime)
895
+ .setTargetAtTime(detune, scheduleTime, timeConstant);
896
+ }
872
897
  setPitchEnvelope(note, scheduleTime) {
873
- const { voiceParams } = note;
898
+ const { bufferSource, voiceParams } = note;
874
899
  const baseRate = voiceParams.playbackRate;
875
- note.bufferSource.playbackRate
900
+ bufferSource.playbackRate
876
901
  .cancelScheduledValues(scheduleTime)
877
- .setValueAtTime(baseRate, note.startTime);
902
+ .setValueAtTime(baseRate, scheduleTime);
878
903
  const modEnvToPitch = voiceParams.modEnvToPitch;
879
904
  if (modEnvToPitch === 0)
880
905
  return;
881
- const basePitch = this.rateToCent(baseRate);
882
- const peekPitch = basePitch + modEnvToPitch;
883
- const peekRate = this.centToRate(peekPitch);
906
+ const peekRate = baseRate * this.centToRate(modEnvToPitch);
884
907
  const modDelay = note.startTime + voiceParams.modDelay;
885
908
  const modAttack = modDelay + voiceParams.modAttack;
886
909
  const modHold = modAttack + voiceParams.modHold;
887
910
  const decayDuration = voiceParams.modDecay;
888
- note.bufferSource.playbackRate
911
+ bufferSource.playbackRate
889
912
  .setValueAtTime(baseRate, modDelay)
890
- .linearRampToValueAtTime(peekRate, modAttack)
913
+ .exponentialRampToValueAtTime(peekRate, modAttack)
891
914
  .setValueAtTime(peekRate, modHold)
892
915
  .setTargetAtTime(baseRate, modHold, decayDuration * decayCurve);
893
916
  }
@@ -918,7 +941,7 @@ class MidyGM1 extends EventTarget {
918
941
  .cancelScheduledValues(scheduleTime)
919
942
  .setValueAtTime(adjustedBaseFreq, startTime)
920
943
  .setValueAtTime(adjustedBaseFreq, modDelay)
921
- .linearRampToValueAtTime(adjustedPeekFreq, modAttack)
944
+ .exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
922
945
  .setValueAtTime(adjustedPeekFreq, modHold)
923
946
  .setTargetAtTime(adjustedSustainFreq, modHold, decayDuration * decayCurve);
924
947
  }
@@ -989,8 +1012,8 @@ class MidyGM1 extends EventTarget {
989
1012
  this.setVolumeEnvelope(note, now);
990
1013
  this.setFilterEnvelope(note, now);
991
1014
  this.setPitchEnvelope(note, now);
992
- this.updateDetune(channel, note, now);
993
- if (0 < state.modulationDepth) {
1015
+ this.setDetune(channel, note, now);
1016
+ if (0 < state.modulationDepthMSB) {
994
1017
  this.startModulation(channel, note, now);
995
1018
  }
996
1019
  note.bufferSource.connect(note.filterNode);
@@ -1070,15 +1093,14 @@ class MidyGM1 extends EventTarget {
1070
1093
  }
1071
1094
  releaseNote(channel, note, endTime) {
1072
1095
  endTime ??= this.audioContext.currentTime;
1073
- const duration = note.voiceParams.volRelease * releaseTime;
1074
- const volRelease = endTime + duration;
1075
- const modRelease = endTime + note.voiceParams.modRelease;
1096
+ const volDuration = note.voiceParams.volRelease;
1097
+ const volRelease = endTime + volDuration;
1076
1098
  note.filterNode.frequency
1077
1099
  .cancelScheduledValues(endTime)
1078
- .linearRampToValueAtTime(note.adjustedBaseFreq, modRelease);
1100
+ .setTargetAtTime(note.adjustedBaseFreq, endTime, note.voiceParams.modRelease * releaseCurve);
1079
1101
  note.volumeEnvelopeNode.gain
1080
1102
  .cancelScheduledValues(endTime)
1081
- .setTargetAtTime(0, endTime, duration * releaseCurve);
1103
+ .setTargetAtTime(0, endTime, volDuration * releaseCurve);
1082
1104
  return new Promise((resolve) => {
1083
1105
  this.scheduleTask(() => {
1084
1106
  const bufferSource = note.bufferSource;
@@ -1274,6 +1296,9 @@ class MidyGM1 extends EventTarget {
1274
1296
  },
1275
1297
  delayVibLFO: (_channel, _note, _scheduleTime) => { },
1276
1298
  freqVibLFO: (_channel, _note, _scheduleTime) => { },
1299
+ detune: (channel, note, scheduleTime) => {
1300
+ this.setDetune(channel, note, scheduleTime);
1301
+ },
1277
1302
  };
1278
1303
  }
1279
1304
  getControllerState(channel, noteNumber, velocity) {
@@ -1354,18 +1379,18 @@ class MidyGM1 extends EventTarget {
1354
1379
  }
1355
1380
  });
1356
1381
  }
1357
- setModulationDepth(channelNumber, modulation, scheduleTime) {
1382
+ setModulationDepth(channelNumber, value, scheduleTime) {
1358
1383
  const channel = this.channels[channelNumber];
1359
1384
  if (!(0 <= scheduleTime))
1360
1385
  scheduleTime = this.audioContext.currentTime;
1361
- channel.state.modulationDepthMSB = modulation / 127;
1386
+ channel.state.modulationDepthMSB = value / 127;
1362
1387
  this.updateModulation(channel, scheduleTime);
1363
1388
  }
1364
- setVolume(channelNumber, volume, scheduleTime) {
1389
+ setVolume(channelNumber, value, scheduleTime) {
1365
1390
  if (!(0 <= scheduleTime))
1366
1391
  scheduleTime = this.audioContext.currentTime;
1367
1392
  const channel = this.channels[channelNumber];
1368
- channel.state.volumeMSB = volume / 127;
1393
+ channel.state.volumeMSB = value / 127;
1369
1394
  this.updateChannelVolume(channel, scheduleTime);
1370
1395
  }
1371
1396
  panToGain(pan) {
@@ -1375,18 +1400,18 @@ class MidyGM1 extends EventTarget {
1375
1400
  gainRight: Math.sin(theta),
1376
1401
  };
1377
1402
  }
1378
- setPan(channelNumber, pan, scheduleTime) {
1403
+ setPan(channelNumber, value, scheduleTime) {
1379
1404
  if (!(0 <= scheduleTime))
1380
1405
  scheduleTime = this.audioContext.currentTime;
1381
1406
  const channel = this.channels[channelNumber];
1382
- channel.state.panMSB = pan / 127;
1407
+ channel.state.panMSB = value / 127;
1383
1408
  this.updateChannelVolume(channel, scheduleTime);
1384
1409
  }
1385
- setExpression(channelNumber, expression, scheduleTime) {
1410
+ setExpression(channelNumber, value, scheduleTime) {
1386
1411
  if (!(0 <= scheduleTime))
1387
1412
  scheduleTime = this.audioContext.currentTime;
1388
1413
  const channel = this.channels[channelNumber];
1389
- channel.state.expressionMSB = expression / 127;
1414
+ channel.state.expressionMSB = value / 127;
1390
1415
  this.updateChannelVolume(channel, scheduleTime);
1391
1416
  }
1392
1417
  dataEntryLSB(channelNumber, value, scheduleTime) {
@@ -1395,14 +1420,14 @@ class MidyGM1 extends EventTarget {
1395
1420
  }
1396
1421
  updateChannelVolume(channel, scheduleTime) {
1397
1422
  const state = channel.state;
1398
- const volume = state.volumeMSB * state.expressionMSB;
1423
+ const gain = state.volumeMSB * state.expressionMSB;
1399
1424
  const { gainLeft, gainRight } = this.panToGain(state.panMSB);
1400
1425
  channel.gainL.gain
1401
1426
  .cancelScheduledValues(scheduleTime)
1402
- .setValueAtTime(volume * gainLeft, scheduleTime);
1427
+ .setValueAtTime(gain * gainLeft, scheduleTime);
1403
1428
  channel.gainR.gain
1404
1429
  .cancelScheduledValues(scheduleTime)
1405
- .setValueAtTime(volume * gainRight, scheduleTime);
1430
+ .setValueAtTime(gain * gainRight, scheduleTime);
1406
1431
  }
1407
1432
  setSustainPedal(channelNumber, value, scheduleTime) {
1408
1433
  const channel = this.channels[channelNumber];
@@ -1457,6 +1482,8 @@ class MidyGM1 extends EventTarget {
1457
1482
  case 2:
1458
1483
  this.handleCoarseTuningRPN(channelNumber, scheduleTime);
1459
1484
  break;
1485
+ case 16383: // NULL
1486
+ break;
1460
1487
  default:
1461
1488
  console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
1462
1489
  }
@@ -1602,9 +1629,9 @@ class MidyGM1 extends EventTarget {
1602
1629
  if (!(0 <= scheduleTime))
1603
1630
  scheduleTime = this.audioContext.currentTime;
1604
1631
  this.mode = "GM1";
1605
- for (let i = 0; i < channels.length; i++) {
1606
- this.allSoundOff(i, 0, scheduleTime);
1607
- const channel = channels[i];
1632
+ for (let ch = 0; ch < channels.length; ch++) {
1633
+ this.allSoundOff(ch, 0, scheduleTime);
1634
+ const channel = channels[ch];
1608
1635
  channel.isDrum = false;
1609
1636
  }
1610
1637
  channels[9].isDrum = true;
@@ -15,6 +15,7 @@ export class MidyGM2 extends EventTarget {
15
15
  coarseTuning: number;
16
16
  };
17
17
  constructor(audioContext: any);
18
+ perceptualSmoothingTime: number;
18
19
  mode: string;
19
20
  masterFineTuning: number;
20
21
  masterCoarseTuning: number;
@@ -75,6 +76,7 @@ export class MidyGM2 extends EventTarget {
75
76
  freqModLFO: (_channel: any, note: any, scheduleTime: any) => void;
76
77
  delayVibLFO: (channel: any, note: any, _scheduleTime: any) => void;
77
78
  freqVibLFO: (channel: any, note: any, scheduleTime: any) => void;
79
+ detune: (channel: any, note: any, scheduleTime: any) => void;
78
80
  };
79
81
  controlChangeHandlers: any[];
80
82
  keyBasedControllerHandlers: any[];
@@ -128,6 +130,7 @@ export class MidyGM2 extends EventTarget {
128
130
  pause(): Promise<void>;
129
131
  resume(): Promise<void>;
130
132
  seekTo(second: any): void;
133
+ tempoChange(tempo: any): void;
131
134
  calcTotalTime(): number;
132
135
  currentTime(): number;
133
136
  processScheduledNotes(channel: any, callback: any): Promise<void>;
@@ -162,14 +165,16 @@ export class MidyGM2 extends EventTarget {
162
165
  centToRate(cent: any): number;
163
166
  centToHz(cent: any): number;
164
167
  calcChannelDetune(channel: any): any;
165
- calcNoteDetune(channel: any, note: any): any;
166
168
  updateChannelDetune(channel: any, scheduleTime: any): void;
167
- updateDetune(channel: any, note: any, scheduleTime: any): void;
169
+ calcScaleOctaveTuning(channel: any, note: any): any;
170
+ calcNoteDetune(channel: any, note: any): any;
168
171
  getPortamentoTime(channel: any, note: any): number;
169
172
  getPitchIncrementSpeed(value: any): number;
170
173
  setPortamentoVolumeEnvelope(channel: any, note: any, scheduleTime: any): void;
171
174
  setVolumeEnvelope(channel: any, note: any, scheduleTime: any): void;
172
- setPortamentoPitchEnvelope(note: any, scheduleTime: any): void;
175
+ setPortamentoDetune(channel: any, note: any, scheduleTime: any): void;
176
+ setDetune(channel: any, note: any, scheduleTime: any): void;
177
+ setPortamentoPitchEnvelope(channel: any, note: any, scheduleTime: any): void;
173
178
  setPitchEnvelope(note: any, scheduleTime: any): void;
174
179
  clampCutoffFrequency(frequency: any): number;
175
180
  setPortamentoFilterEnvelope(channel: any, note: any, scheduleTime: any): void;
@@ -204,8 +209,8 @@ export class MidyGM2 extends EventTarget {
204
209
  setChorusSend(channel: any, note: any, scheduleTime: any): void;
205
210
  setDelayModLFO(note: any): void;
206
211
  setFreqModLFO(note: any, scheduleTime: any): void;
207
- setFreqVibLFO(channel: any, note: any, scheduleTime: any): void;
208
212
  setDelayVibLFO(channel: any, note: any): void;
213
+ setFreqVibLFO(channel: any, note: any, scheduleTime: any): void;
209
214
  createVoiceParamsHandlers(): {
210
215
  modLfoToPitch: (channel: any, note: any, scheduleTime: any) => void;
211
216
  vibLfoToPitch: (channel: any, note: any, scheduleTime: any) => void;
@@ -217,6 +222,7 @@ export class MidyGM2 extends EventTarget {
217
222
  freqModLFO: (_channel: any, note: any, scheduleTime: any) => void;
218
223
  delayVibLFO: (channel: any, note: any, _scheduleTime: any) => void;
219
224
  freqVibLFO: (channel: any, note: any, scheduleTime: any) => void;
225
+ detune: (channel: any, note: any, scheduleTime: any) => void;
220
226
  };
221
227
  getControllerState(channel: any, noteNumber: any, velocity: any): Float32Array<any>;
222
228
  applyVoiceParams(channel: any, controllerType: any, scheduleTime: any): void;
@@ -224,16 +230,16 @@ export class MidyGM2 extends EventTarget {
224
230
  setControlChange(channelNumber: any, controllerType: any, value: any, scheduleTime: any): void;
225
231
  setBankMSB(channelNumber: any, msb: any): void;
226
232
  updateModulation(channel: any, scheduleTime: any): void;
227
- setModulationDepth(channelNumber: any, modulation: any, scheduleTime: any): void;
233
+ setModulationDepth(channelNumber: any, value: any, scheduleTime: any): void;
228
234
  updatePortamento(channel: any, scheduleTime: any): void;
229
- setPortamentoTime(channelNumber: any, portamentoTime: any, scheduleTime: any): void;
230
- setVolume(channelNumber: any, volume: any, scheduleTime: any): void;
235
+ setPortamentoTime(channelNumber: any, value: any, scheduleTime: any): void;
236
+ setVolume(channelNumber: any, value: any, scheduleTime: any): void;
231
237
  panToGain(pan: any): {
232
238
  gainLeft: number;
233
239
  gainRight: number;
234
240
  };
235
- setPan(channelNumber: any, pan: any, scheduleTime: any): void;
236
- setExpression(channelNumber: any, expression: any, scheduleTime: any): void;
241
+ setPan(channelNumber: any, value: any, scheduleTime: any): void;
242
+ setExpression(channelNumber: any, value: any, scheduleTime: any): void;
237
243
  setBankLSB(channelNumber: any, lsb: any): void;
238
244
  dataEntryLSB(channelNumber: any, value: any, scheduleTime: any): void;
239
245
  updateChannelVolume(channel: any, scheduleTime: any): 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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"}