@marmooo/midy 0.2.0 → 0.2.1

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.
@@ -596,16 +596,35 @@ class MidyGM1 {
596
596
  cbToRatio(cb) {
597
597
  return Math.pow(10, cb / 200);
598
598
  }
599
+ rateToCent(rate) {
600
+ return 1200 * Math.log2(rate);
601
+ }
602
+ centToRate(cent) {
603
+ return Math.pow(2, cent / 1200);
604
+ }
599
605
  centToHz(cent) {
600
- return 8.176 * Math.pow(2, cent / 1200);
606
+ return 8.176 * this.centToRate(cent);
601
607
  }
602
- calcSemitoneOffset(channel) {
608
+ calcChannelDetune(channel) {
603
609
  const tuning = channel.coarseTuning + channel.fineTuning;
604
610
  const pitchWheel = channel.state.pitchWheel * 2 - 1;
605
- const pitchWheelSensitivity = channel.state.pitchWheelSensitivity * 128;
611
+ const pitchWheelSensitivity = channel.state.pitchWheelSensitivity * 12800;
606
612
  const pitch = pitchWheel * pitchWheelSensitivity;
607
613
  return tuning + pitch;
608
614
  }
615
+ updateDetune(channel) {
616
+ const now = this.audioContext.currentTime;
617
+ channel.scheduledNotes.forEach((noteList) => {
618
+ for (let i = 0; i < noteList.length; i++) {
619
+ const note = noteList[i];
620
+ if (!note)
621
+ continue;
622
+ note.bufferSource.detune
623
+ .cancelScheduledValues(now)
624
+ .setValueAtTime(channel.detune, now);
625
+ }
626
+ });
627
+ }
609
628
  setVolumeEnvelope(note) {
610
629
  const now = this.audioContext.currentTime;
611
630
  const { voiceParams, startTime } = note;
@@ -623,32 +642,28 @@ class MidyGM1 {
623
642
  .setValueAtTime(attackVolume, volHold)
624
643
  .linearRampToValueAtTime(sustainVolume, volDecay);
625
644
  }
626
- setPlaybackRate(note) {
645
+ setPitchEnvelope(note) {
627
646
  const now = this.audioContext.currentTime;
647
+ const { voiceParams } = note;
648
+ const baseRate = voiceParams.playbackRate;
628
649
  note.bufferSource.playbackRate
629
650
  .cancelScheduledValues(now)
630
- .setValueAtTime(note.voiceParams.playbackRate, now);
631
- }
632
- setPitch(channel, note) {
633
- const now = this.audioContext.currentTime;
634
- const { startTime } = note;
635
- const basePitch = this.calcSemitoneOffset(channel) * 100;
636
- note.bufferSource.detune
637
- .cancelScheduledValues(now)
638
- .setValueAtTime(basePitch, startTime);
639
- const modEnvToPitch = note.voiceParams.modEnvToPitch;
651
+ .setValueAtTime(baseRate, now);
652
+ const modEnvToPitch = voiceParams.modEnvToPitch;
640
653
  if (modEnvToPitch === 0)
641
654
  return;
655
+ const basePitch = this.rateToCent(baseRate);
642
656
  const peekPitch = basePitch + modEnvToPitch;
657
+ const peekRate = this.centToRate(peekPitch);
643
658
  const modDelay = startTime + voiceParams.modDelay;
644
659
  const modAttack = modDelay + voiceParams.modAttack;
645
660
  const modHold = modAttack + voiceParams.modHold;
646
661
  const modDecay = modHold + voiceParams.modDecay;
647
- note.bufferSource.detune
648
- .setValueAtTime(basePitch, modDelay)
649
- .exponentialRampToValueAtTime(peekPitch, modAttack)
650
- .setValueAtTime(peekPitch, modHold)
651
- .linearRampToValueAtTime(basePitch, modDecay);
662
+ note.bufferSource.playbackRate
663
+ .setValueAtTime(baseRate, modDelay)
664
+ .exponentialRampToValueAtTime(peekRate, modAttack)
665
+ .setValueAtTime(peekRate, modHold)
666
+ .linearRampToValueAtTime(baseRate, modDecay);
652
667
  }
653
668
  clampCutoffFrequency(frequency) {
654
669
  const minFrequency = 20; // min Hz of initialFilterFc
@@ -709,9 +724,8 @@ class MidyGM1 {
709
724
  });
710
725
  this.setVolumeEnvelope(note);
711
726
  this.setFilterEnvelope(note);
712
- this.setPlaybackRate(note);
727
+ this.setPitchEnvelope(note);
713
728
  if (0 < state.modulationDepth) {
714
- this.setPitch(channel, note);
715
729
  this.startModulation(channel, note, startTime);
716
730
  }
717
731
  note.bufferSource.connect(note.filterNode);
@@ -859,10 +873,12 @@ class MidyGM1 {
859
873
  setPitchBend(channelNumber, value) {
860
874
  const channel = this.channels[channelNumber];
861
875
  const state = channel.state;
876
+ const prev = state.pitchWheel * 2 - 1;
877
+ const next = (value - 8192) / 8192;
862
878
  state.pitchWheel = value / 16383;
863
- const pitchWheel = (value - 8192) / 8192;
864
- const detuneChange = pitchWheel * state.pitchWheelSensitivity * 12800;
865
- this.updateDetune(channel, detuneChange);
879
+ channel.detune += (next - prev) * state.pitchWheelSensitivity * 12800;
880
+ this.updateDetune(channel);
881
+ this.applyVoiceParams(channel, 14);
866
882
  }
867
883
  setModLfoToPitch(channel, note) {
868
884
  const now = this.audioContext.currentTime;
@@ -874,15 +890,6 @@ class MidyGM1 {
874
890
  .cancelScheduledValues(now)
875
891
  .setValueAtTime(modulationDepth * modulationDepthSign, now);
876
892
  }
877
- setModLfoToVolume(note) {
878
- const now = this.audioContext.currentTime;
879
- const modLfoToVolume = note.voiceParams.modLfoToVolume;
880
- const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
881
- const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
882
- note.volumeDepth.gain
883
- .cancelScheduledValues(now)
884
- .setValueAtTime(volumeDepth * volumeDepthSign, now);
885
- }
886
893
  setVibLfoToPitch(channel, note) {
887
894
  const now = this.audioContext.currentTime;
888
895
  const vibLfoToPitch = note.voiceParams.vibLfoToPitch;
@@ -900,6 +907,15 @@ class MidyGM1 {
900
907
  .cancelScheduledValues(now)
901
908
  .setValueAtTime(modLfoToFilterFc, now);
902
909
  }
910
+ setModLfoToVolume(note) {
911
+ const now = this.audioContext.currentTime;
912
+ const modLfoToVolume = note.voiceParams.modLfoToVolume;
913
+ const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
914
+ const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
915
+ note.volumeDepth.gain
916
+ .cancelScheduledValues(now)
917
+ .setValueAtTime(volumeDepth * volumeDepthSign, now);
918
+ }
903
919
  setDelayModLFO(note) {
904
920
  const now = this.audioContext.currentTime;
905
921
  const startTime = note.startTime;
@@ -999,7 +1015,7 @@ class MidyGM1 {
999
1015
  noteVoiceParams[key] = voiceParams[key];
1000
1016
  }
1001
1017
  this.setFilterEnvelope(channel, note);
1002
- this.setPitch(channel, note);
1018
+ this.setPitchEnvelope(note);
1003
1019
  }
1004
1020
  else if (volumeEnvelopeKeySet.has(key)) {
1005
1021
  if (appliedVolumeEnvelope)
@@ -1053,7 +1069,7 @@ class MidyGM1 {
1053
1069
  note.modulationDepth.gain.setValueAtTime(channel.state.modulationDepth, now);
1054
1070
  }
1055
1071
  else {
1056
- this.setPitch(channel, note);
1072
+ this.setPitchEnvelope(note);
1057
1073
  this.startModulation(channel, note, now);
1058
1074
  }
1059
1075
  }
@@ -1162,59 +1178,49 @@ class MidyGM1 {
1162
1178
  this.channels[channelNumber].dataMSB = value;
1163
1179
  this.handleRPN(channelNumber);
1164
1180
  }
1165
- updateDetune(channel, detune) {
1166
- const now = this.audioContext.currentTime;
1167
- channel.scheduledNotes.forEach((noteList) => {
1168
- for (let i = 0; i < noteList.length; i++) {
1169
- const note = noteList[i];
1170
- if (!note)
1171
- continue;
1172
- const { bufferSource } = note;
1173
- bufferSource.detune
1174
- .cancelScheduledValues(now)
1175
- .setValueAtTime(detune, now);
1176
- }
1177
- });
1178
- }
1179
1181
  handlePitchBendRangeRPN(channelNumber) {
1180
1182
  const channel = this.channels[channelNumber];
1181
1183
  this.limitData(channel, 0, 127, 0, 99);
1182
1184
  const pitchBendRange = channel.dataMSB + channel.dataLSB / 100;
1183
1185
  this.setPitchBendRange(channelNumber, pitchBendRange);
1184
1186
  }
1185
- setPitchBendRange(channelNumber, pitchWheelSensitivity) {
1187
+ setPitchBendRange(channelNumber, value) {
1186
1188
  const channel = this.channels[channelNumber];
1187
1189
  const state = channel.state;
1188
- state.pitchWheelSensitivity = pitchWheelSensitivity / 128;
1189
- const detune = (state.pitchWheel * 2 - 1) * pitchWheelSensitivity * 100;
1190
- this.updateDetune(channel, detune);
1190
+ const prev = state.pitchWheelSensitivity;
1191
+ const next = value / 128;
1192
+ state.pitchWheelSensitivity = next;
1193
+ channel.detune += (state.pitchWheel * 2 - 1) * (next - prev) * 12800;
1194
+ this.updateDetune(channel);
1191
1195
  this.applyVoiceParams(channel, 16);
1192
1196
  }
1193
1197
  handleFineTuningRPN(channelNumber) {
1194
1198
  const channel = this.channels[channelNumber];
1195
1199
  this.limitData(channel, 0, 127, 0, 127);
1196
- const fineTuning = (channel.dataMSB * 128 + channel.dataLSB - 8192) / 8192;
1200
+ const fineTuning = channel.dataMSB * 128 + channel.dataLSB;
1197
1201
  this.setFineTuning(channelNumber, fineTuning);
1198
1202
  }
1199
- setFineTuning(channelNumber, fineTuning) {
1203
+ setFineTuning(channelNumber, value) {
1200
1204
  const channel = this.channels[channelNumber];
1201
- const prevFineTuning = channel.fineTuning;
1202
- channel.fineTuning = fineTuning;
1203
- const detuneChange = channel.fineTuning - prevFineTuning;
1204
- this.updateDetune(channel, detuneChange);
1205
+ const prev = channel.fineTuning;
1206
+ const next = (value - 8192) / 8.192; // cent
1207
+ channel.fineTuning = next;
1208
+ channel.detune += next - prev;
1209
+ this.updateDetune(channel);
1205
1210
  }
1206
1211
  handleCoarseTuningRPN(channelNumber) {
1207
1212
  const channel = this.channels[channelNumber];
1208
1213
  this.limitDataMSB(channel, 0, 127);
1209
- const coarseTuning = channel.dataMSB - 64;
1210
- this.setFineTuning(channelNumber, coarseTuning);
1214
+ const coarseTuning = channel.dataMSB;
1215
+ this.setCoarseTuning(channelNumber, coarseTuning);
1211
1216
  }
1212
- setCoarseTuning(channelNumber, coarseTuning) {
1217
+ setCoarseTuning(channelNumber, value) {
1213
1218
  const channel = this.channels[channelNumber];
1214
- const prevCoarseTuning = channel.coarseTuning;
1215
- channel.coarseTuning = coarseTuning;
1216
- const detuneChange = channel.coarseTuning - prevCoarseTuning;
1217
- this.updateDetune(channel, detuneChange);
1219
+ const prev = channel.coarseTuning;
1220
+ const next = (value - 64) * 100; // cent
1221
+ channel.coarseTuning = next;
1222
+ channel.detune += next - prev;
1223
+ this.updateDetune(channel);
1218
1224
  }
1219
1225
  allSoundOff(channelNumber) {
1220
1226
  return this.stopChannelNotes(channelNumber, 0, true);
@@ -1328,6 +1334,7 @@ Object.defineProperty(MidyGM1, "channelSettings", {
1328
1334
  writable: true,
1329
1335
  value: {
1330
1336
  currentBufferSource: null,
1337
+ detune: 0,
1331
1338
  program: 0,
1332
1339
  bank: 0,
1333
1340
  dataMSB: 0,
@@ -1,6 +1,8 @@
1
1
  export class MidyGM2 {
2
2
  static channelSettings: {
3
3
  currentBufferSource: null;
4
+ detune: number;
5
+ scaleOctaveTuningTable: any[];
4
6
  program: number;
5
7
  bank: number;
6
8
  bankMSB: number;
@@ -182,12 +184,15 @@ export class MidyGM2 {
182
184
  feedbackGains: any[];
183
185
  };
184
186
  cbToRatio(cb: any): number;
187
+ rateToCent(rate: any): number;
188
+ centToRate(cent: any): number;
185
189
  centToHz(cent: any): number;
186
- calcSemitoneOffset(channel: any): any;
190
+ calcDetune(channel: any, note: any): any;
191
+ calcNoteDetune(channel: any, note: any): any;
192
+ updateDetune(channel: any): void;
187
193
  setPortamentoStartVolumeEnvelope(channel: any, note: any): void;
188
194
  setVolumeEnvelope(note: any): void;
189
- setPlaybackRate(note: any): void;
190
- setPitch(channel: any, note: any): void;
195
+ setPitchEnvelope(note: any): void;
191
196
  clampCutoffFrequency(frequency: any): number;
192
197
  setPortamentoStartFilterEnvelope(channel: any, note: any): void;
193
198
  setFilterEnvelope(channel: any, note: any): void;
@@ -208,11 +213,11 @@ export class MidyGM2 {
208
213
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
209
214
  setPitchBend(channelNumber: any, value: any): void;
210
215
  setModLfoToPitch(channel: any, note: any): void;
216
+ setVibLfoToPitch(channel: any, note: any): void;
217
+ setModLfoToFilterFc(note: any): void;
211
218
  setModLfoToVolume(note: any): void;
212
219
  setChorusEffectsSend(note: any, prevValue: any): void;
213
220
  setReverbEffectsSend(note: any, prevValue: any): void;
214
- setVibLfoToPitch(channel: any, note: any): void;
215
- setModLfoToFilterFc(note: any): void;
216
221
  setDelayModLFO(note: any): void;
217
222
  setFreqModLFO(note: any): void;
218
223
  createVoiceParamsHandlers(): {
@@ -282,13 +287,12 @@ export class MidyGM2 {
282
287
  setRPNMSB(channelNumber: any, value: any): void;
283
288
  setRPNLSB(channelNumber: any, value: any): void;
284
289
  dataEntryMSB(channelNumber: any, value: any): void;
285
- updateDetune(channel: any, detune: any): void;
286
290
  handlePitchBendRangeRPN(channelNumber: any): void;
287
- setPitchBendRange(channelNumber: any, pitchWheelSensitivity: any): void;
291
+ setPitchBendRange(channelNumber: any, value: any): void;
288
292
  handleFineTuningRPN(channelNumber: any): void;
289
- setFineTuning(channelNumber: any, fineTuning: any): void;
293
+ setFineTuning(channelNumber: any, value: any): void;
290
294
  handleCoarseTuningRPN(channelNumber: any): void;
291
- setCoarseTuning(channelNumber: any, coarseTuning: any): void;
295
+ setCoarseTuning(channelNumber: any, value: any): void;
292
296
  handleModulationDepthRangeRPN(channelNumber: any): void;
293
297
  setModulationDepthRange(channelNumber: any, modulationDepthRange: any): void;
294
298
  allSoundOff(channelNumber: any): Promise<void>;
@@ -305,9 +309,11 @@ export class MidyGM2 {
305
309
  handleMasterVolumeSysEx(data: any): void;
306
310
  setMasterVolume(volume: any): void;
307
311
  handleMasterFineTuningSysEx(data: any): void;
308
- setMasterFineTuning(fineTuning: any): void;
312
+ setMasterFineTuning(value: any): void;
309
313
  handleMasterCoarseTuningSysEx(data: any): void;
310
- setMasterCoarseTuning(coarseTuning: any): void;
314
+ setMasterCoarseTuning(value: any): void;
315
+ getChannelBitmap(data: any): any[];
316
+ handleScaleOctaveTuning1ByteFormat(data: any): void;
311
317
  handleGlobalParameterControlSysEx(data: any): void;
312
318
  handleReverbParameterSysEx(data: any): void;
313
319
  setReverbType(type: 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":"AA8GA;IAmCE;;;;;;;;;;;;;;;MAeE;IAEF;;;;;;;MAOE;IAgCF;;;;;OAaC;IAvGD,qBAAmB;IACnB,kBAAc;IACd,yBAAqB;IACrB,2BAAuB;IACvB;;;MAGE;IACF;;;;;;MAME;IACF,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;IAClB,iCAA8B;IA4B9B;;;;;MA4BE;IAGA,kBAAgC;IAChC;;;;;MAAqD;IACrD,gBAA4C;IAC5C;;;;;;;;;;;MAA2D;IAC3D;;;;;;;;;;;;;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IACjD;;;MAA8D;IAC9D;;;;;;;;MAAyD;IAO3D,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAcC;IAED,6DA2BC;IAED,iEAUC;IAED,2CAcC;IAED,2EAuDC;IAED,mCAOC;IAED,0BAkDC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAoGC;IAED,+EAoBC;IAED,qDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,kFAuBC;IAED;;;;MAWC;IAED,gFAUC;IAED,mFAYC;IAED,sGAcC;IAID;;;MA8BC;IAED;;;;;;;;MA0CC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,yCAUC;IAED,6CAEC;IAED,iCAaC;IAED,gEAWC;IAED,mCAgBC;IAED,kCAqBC;IAED,6CAIC;IAED,gEAsBC;IAED,iDA2BC;IAED,+DAoBC;IAED,4DAcC;IAED,iIAuDC;IAED,gDAQC;IAED,mHA0DC;IAED,2FASC;IAED,qFAkCC;IAED,wJAuCC;IAED,qHAUC;IAED,kEAeC;IAED,oEAYC;IAED,gFAmBC;IAED,4DAIC;IAED,+DAeC;IAED,qEAGC;IAED,mDASC;IAED,gDASC;IAED,gDASC;IAED,qCAMC;IAED,mCAQC;IAED,sDAsBC;IAED,sDAsBC;IAED,gCAOC;IAED,+BAMC;IAED;;;;;;;;;;;MA+CC;IAED,+EAMC;IAED,0DAiDC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;MA2BC;IAED,+EAYC;IAED,+CAEC;IAED,qCAiBC;IAED,8DAKC;IAED,iEAIC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,+CAEC;IAED,mDAGC;IAED,wCAWC;IAED,sDAKC;IAED,oDAEC;IAED,mEAmCC;IAED,mEAmCC;IAED,wDAUC;IAED,uDAGC;IAED,kFAeC;IAED,2DAMC;IAED,oCAqBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,kDAKC;IAED,wDASC;IAED,8CAKC;IAED,oDAOC;IAED,gDAKC;IAED,sDAOC;IAED,wDAKC;IAED,6EAKC;IAED,+CAEC;IAED,8CAyBC;IAED,+CAEC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DA4BC;IAED,oBASC;IAED,oBASC;IAED,yDAwCC;IAED,yCAGC;IAED,mCAQC;IAED,6CAGC;IAED,sCAMC;IAED,+CAGC;IAED,wCAMC;IAED,mCAeC;IAED,oDAaC;IAED,mDAeC;IAED,4CAOC;IAED,+BAKC;IAED,qDAiBC;IAED,gCAIC;IAED,kCAEC;IA6BD,4CAEC;IAED,4CAaC;IAED,+BAiBC;IAED,wFAKC;IAED,mCAKC;IAED,qCAEC;IAED,oCAOC;IAED,sCAEC;IAED,oCAUC;IAED,sCAEC;IAED,wCAuBC;IAED,0CAEC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAnzED;IAaE,0FAMC;IAlBD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAChB,gBAAW;IACX,kBAAa;IACb,uBAAkB;IAClB,uBAAkB;IAClB,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}