@marmooo/midy 0.0.6 → 0.0.7

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
@@ -651,14 +651,16 @@ export class Midy {
651
651
  connectNoteEffects(channel, gainNode) {
652
652
  if (channel.reverb === 0) {
653
653
  if (channel.chorus === 0) { // no effect
654
- gainNode.connect(channel.pannerNode);
654
+ gainNode.connect(channel.gainL);
655
+ gainNode.connect(channel.gainR);
655
656
  }
656
657
  else { // chorus
657
658
  channel.chorusEffect.delayNodes.forEach((delayNode) => {
658
659
  gainNode.connect(delayNode);
659
660
  });
660
661
  channel.chorusEffect.chorusGains.forEach((chorusGain) => {
661
- chorusGain.connect(channel.pannerNode);
662
+ chorusGain.connect(channel.gainL);
663
+ chorusGain.connect(channel.gainR);
662
664
  });
663
665
  }
664
666
  }
@@ -977,20 +979,12 @@ export class Midy {
977
979
  this.setPitchBend(channelNumber, pitchBend);
978
980
  }
979
981
  setPitchBend(channelNumber, pitchBend) {
980
- const now = this.audioContext.currentTime;
981
982
  const channel = this.channels[channelNumber];
982
983
  const prevPitchBend = channel.pitchBend;
983
984
  channel.pitchBend = (pitchBend - 8192) / 8192;
984
985
  const detuneChange = (channel.pitchBend - prevPitchBend) *
985
986
  channel.pitchBendRange * 100;
986
- const activeNotes = this.getActiveNotes(channel, now);
987
- activeNotes.forEach((activeNote) => {
988
- const { bufferSource } = activeNote;
989
- const detune = bufferSource.detune.value + detuneChange;
990
- bufferSource.detune
991
- .cancelScheduledValues(now)
992
- .setValueAtTime(detune, now);
993
- });
987
+ this.updateDetune(channel, detuneChange);
994
988
  }
995
989
  handleControlChange(channelNumber, controller, value) {
996
990
  switch (controller) {
@@ -1031,14 +1025,14 @@ export class Midy {
1031
1025
  return this.setReverb(channelNumber, value);
1032
1026
  case 93:
1033
1027
  return this.setChorus(channelNumber, value);
1034
- case 96:
1028
+ case 96: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp18.pdf
1035
1029
  return incrementRPNValue(channelNumber);
1036
- case 97:
1030
+ case 97: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp18.pdf
1037
1031
  return decrementRPNValue(channelNumber);
1038
1032
  case 100:
1039
- return this.setRPNMSB(channelNumber, value);
1040
- case 101:
1041
1033
  return this.setRPNLSB(channelNumber, value);
1034
+ case 101:
1035
+ return this.setRPNMSB(channelNumber, value);
1042
1036
  case 120:
1043
1037
  return this.allSoundOff(channelNumber);
1044
1038
  case 121:
@@ -1175,39 +1169,58 @@ export class Midy {
1175
1169
  const channel = this.channels[channelNumber];
1176
1170
  channel.vibratoDelay = vibratoDelay / 127 * 5; // 0-5sec
1177
1171
  }
1178
- incrementRPNValue(channelNumber) {
1172
+ limitData(channel, minMSB, maxMSB, minLSB, maxLSB) {
1173
+ if (maxLSB < channel.dataLSB) {
1174
+ channel.dataMSB++;
1175
+ channel.dataLSB = minLSB;
1176
+ }
1177
+ else if (channel.dataLSB < 0) {
1178
+ channel.dataMSB--;
1179
+ channel.dataLSB = maxLSB;
1180
+ }
1181
+ if (maxMSB < channel.dataMSB) {
1182
+ channel.dataMSB = maxMSB;
1183
+ channel.dataLSB = maxLSB;
1184
+ }
1185
+ else if (channel.dataMSB < 0) {
1186
+ channel.dataMSB = minMSB;
1187
+ channel.dataLSB = minLSB;
1188
+ }
1189
+ }
1190
+ limitDataMSB(channel, minMSB, maxMSB) {
1191
+ if (maxMSB < channel.dataMSB) {
1192
+ channel.dataMSB = maxMSB;
1193
+ }
1194
+ else if (channel.dataMSB < 0) {
1195
+ channel.dataMSB = minMSB;
1196
+ }
1197
+ }
1198
+ // TODO: support 3-4?
1199
+ handleRPN(channelNumber, value) {
1179
1200
  const channel = this.channels[channelNumber];
1180
1201
  const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
1181
1202
  switch (rpn) {
1182
1203
  case 0:
1183
- channel.pitchBendRange = Math.min(1, channel.pitchBendRange + 1);
1204
+ channel.dataLSB += value;
1205
+ this.handlePitchBendRangeMessage(channelNumber);
1184
1206
  break;
1185
1207
  case 1:
1186
- channel.fineTuning = Math.min(1, channel.fineTuning + 1);
1208
+ channel.dataLSB += value;
1209
+ this.handleFineTuningMessage(channelNumber);
1187
1210
  break;
1188
1211
  case 2:
1189
- channel.coarseTuning = Math.min(88, channel.coarseTuning + 1);
1212
+ channel.dataMSB += value;
1213
+ this.handleCoarseTuningMessage(channelNumber);
1190
1214
  break;
1191
1215
  default:
1192
1216
  console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
1193
1217
  }
1194
1218
  }
1219
+ incrementRPNValue(channelNumber) {
1220
+ this.handleRPN(channelNumber, 1);
1221
+ }
1195
1222
  decrementRPNValue(channelNumber) {
1196
- const channel = this.channels[channelNumber];
1197
- const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
1198
- switch (rpn) {
1199
- case 0:
1200
- channel.pitchBendRange = Math.max(-1, channel.pitchBendRange - 1);
1201
- break;
1202
- case 1:
1203
- channel.fineTuning = Math.max(-1, channel.fineTuning - 1);
1204
- break;
1205
- case 2:
1206
- channel.coarseTuning = Math.max(40, channel.coarseTuning - 1);
1207
- break;
1208
- default:
1209
- console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB}, LSB=${channel.rpnLSB}.`);
1210
- }
1223
+ this.handleRPN(channelNumber, -1);
1211
1224
  }
1212
1225
  setRPNMSB(channelNumber, value) {
1213
1226
  this.channels[channelNumber].rpnMSB = value;
@@ -1215,39 +1228,13 @@ export class Midy {
1215
1228
  setRPNLSB(channelNumber, value) {
1216
1229
  this.channels[channelNumber].rpnLSB = value;
1217
1230
  }
1218
- // TODO: support 3-4?
1219
1231
  setDataEntry(channelNumber, value, isMSB) {
1220
1232
  const channel = this.channels[channelNumber];
1221
- const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
1222
1233
  isMSB ? channel.dataMSB = value : channel.dataLSB = value;
1223
- const { dataMSB, dataLSB } = channel;
1224
- switch (rpn) {
1225
- case 0:
1226
- return this.handlePitchBendRangeMessage(channelNumber, dataMSB, dataLSB);
1227
- case 1:
1228
- channel.fineTuning = (dataMSB * 128 + dataLSB - 8192) / 8192;
1229
- break;
1230
- case 2:
1231
- channel.coarseTuning = dataMSB - 64;
1232
- break;
1233
- case 5:
1234
- channel.modulationDepthRange = dataMSB + dataLSB / 128;
1235
- break;
1236
- default:
1237
- console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
1238
- }
1234
+ this.handleRPN(channelNumber, 0);
1239
1235
  }
1240
- handlePitchBendRangeMessage(channelNumber, dataMSB, dataLSB) {
1241
- const pitchBendRange = dataMSB + dataLSB / 100;
1242
- this.setPitchBendRange(channelNumber, pitchBendRange);
1243
- }
1244
- setPitchBendRange(channelNumber, pitchBendRange) {
1236
+ updateDetune(channel, detuneChange) {
1245
1237
  const now = this.audioContext.currentTime;
1246
- const channel = this.channels[channelNumber];
1247
- const prevPitchBendRange = channel.pitchBendRange;
1248
- channel.pitchBendRange = pitchBendRange;
1249
- const detuneChange = (channel.pitchBendRange - prevPitchBendRange) *
1250
- channel.pitchBend * 100;
1251
1238
  const activeNotes = this.getActiveNotes(channel, now);
1252
1239
  activeNotes.forEach((activeNote) => {
1253
1240
  const { bufferSource } = activeNote;
@@ -1257,6 +1244,40 @@ export class Midy {
1257
1244
  .setValueAtTime(detune, now);
1258
1245
  });
1259
1246
  }
1247
+ handlePitchBendRangeMessage(channelNumber) {
1248
+ const channel = this.channels[channelNumber];
1249
+ this.limitData(channel, 0, 127, 0, 99);
1250
+ const pitchBendRange = channel.dataMSB + channel.dataLSB / 100;
1251
+ this.setPitchBendRange(channelNumber, pitchBendRange);
1252
+ }
1253
+ setPitchBendRange(channelNumber, pitchBendRange) {
1254
+ const channel = this.channels[channelNumber];
1255
+ const prevPitchBendRange = channel.pitchBendRange;
1256
+ channel.pitchBendRange = pitchBendRange;
1257
+ const detuneChange = (channel.pitchBendRange - prevPitchBendRange) *
1258
+ channel.pitchBend * 100;
1259
+ this.updateDetune(channel, detuneChange);
1260
+ }
1261
+ handleFineTuningMessage(channelNumber) {
1262
+ const channel = this.channels[channelNumber];
1263
+ this.limitData(channel, 0, 127, 0, 127);
1264
+ const fineTuning = (channel.dataMSB * 128 + channel.dataLSB - 8192) / 8192;
1265
+ this.setFineTuning(channelNumber, fineTuning);
1266
+ }
1267
+ setFineTuning(channelNumber, fineTuning) {
1268
+ const channel = this.channels[channelNumber];
1269
+ channel.fineTuning = fineTuning;
1270
+ }
1271
+ handleCoarseTuningMessage(channelNumber) {
1272
+ const channel = this.channels[channelNumber];
1273
+ this.limitDataMSB(channel, 0, 127);
1274
+ const coarseTuning = channel.dataMSB - 64;
1275
+ this.setFineTuning(channelNumber, coarseTuning);
1276
+ }
1277
+ setCoarseTuning(channelNumber, coarseTuning) {
1278
+ const channel = this.channels[channelNumber];
1279
+ channel.fineTuning = coarseTuning;
1280
+ }
1260
1281
  allSoundOff(channelNumber) {
1261
1282
  const now = this.audioContext.currentTime;
1262
1283
  const channel = this.channels[channelNumber];
@@ -1328,8 +1349,8 @@ export class Midy {
1328
1349
  channel.bankLSB = 0;
1329
1350
  channel.bank = 0;
1330
1351
  });
1331
- this.channels[9].bankMSB = 120;
1332
- this.channels[9].bank = 120 * 128;
1352
+ this.channels[9].bankMSB = 1;
1353
+ this.channels[9].bank = 128;
1333
1354
  }
1334
1355
  GM2SystemOn() {
1335
1356
  this.channels.forEach((channel) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marmooo/midy",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
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",
@@ -140,11 +140,19 @@ export class MidyGM1 {
140
140
  setExpression(channelNumber: any, expression: any): void;
141
141
  updateChannelGain(channel: any): void;
142
142
  setSustainPedal(channelNumber: any, value: any): void;
143
+ limitData(channel: any, minMSB: any, maxMSB: any, minLSB: any, maxLSB: any): void;
144
+ limitDataMSB(channel: any, minMSB: any, maxMSB: any): void;
145
+ handleRPN(channelNumber: any): void;
143
146
  setRPNMSB(channelNumber: any, value: any): void;
144
147
  setRPNLSB(channelNumber: any, value: any): void;
145
148
  setDataEntry(channelNumber: any, value: any, isMSB: any): void;
146
- handlePitchBendRangeMessage(channelNumber: any, dataMSB: any, dataLSB: any): void;
149
+ updateDetune(channel: any, detuneChange: any): void;
150
+ handlePitchBendRangeMessage(channelNumber: any): void;
147
151
  setPitchBendRange(channelNumber: any, pitchBendRange: any): void;
152
+ handleFineTuningMessage(channelNumber: any): void;
153
+ setFineTuning(channelNumber: any, fineTuning: any): void;
154
+ handleCoarseTuningMessage(channelNumber: any): void;
155
+ setCoarseTuning(channelNumber: any, coarseTuning: any): void;
148
156
  allSoundOff(channelNumber: any): any[];
149
157
  resetAllControllers(channelNumber: any): void;
150
158
  allNotesOff(channelNumber: any): any[];
@@ -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;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;MAYC;IAED;;;;;;;;;;;;;;;;;;;;QAUC;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,sDAEC;IAED,2BAEC;IAED,4BAEC;IAED,sCAGC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHA6BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIAmDC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAeC;IAED,mFA+BC;IAED,yDAiBC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,sCAUC;IAED,sDAMC;IAED,gDAEC;IAED,gDAEC;IAED,+DAuBC;IAED,kFAGC;IAED,iEAeC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAz/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-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;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;MAYC;IAED;;;;;;;;;;;;;;;;;;;;QAUC;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,sDAGC;IAED,2BAEC;IAED,4BAEC;IAED,sCAGC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHA6BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIAmDC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,mFA+BC;IAED,yDAiBC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,sCAUC;IAED,sDAMC;IAED,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,+DAIC;IAED,oDAUC;IAED,sDAKC;IAED,iEAOC;IAED,kDAKC;IAED,yDAGC;IAED,oDAKC;IAED,6DAGC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AA1iCD;IAOE,gFAKC;IAXD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
@@ -495,7 +495,8 @@ class MidyGM1 {
495
495
  return noteList[0];
496
496
  }
497
497
  connectNoteEffects(channel, gainNode) {
498
- gainNode.connect(channel.pannerNode);
498
+ gainNode.connect(channel.gainL);
499
+ gainNode.connect(channel.gainR);
499
500
  }
500
501
  cbToRatio(cb) {
501
502
  return Math.pow(10, cb / 200);
@@ -706,20 +707,12 @@ class MidyGM1 {
706
707
  this.setPitchBend(channelNumber, pitchBend);
707
708
  }
708
709
  setPitchBend(channelNumber, pitchBend) {
709
- const now = this.audioContext.currentTime;
710
710
  const channel = this.channels[channelNumber];
711
711
  const prevPitchBend = channel.pitchBend;
712
712
  channel.pitchBend = (pitchBend - 8192) / 8192;
713
713
  const detuneChange = (channel.pitchBend - prevPitchBend) *
714
714
  channel.pitchBendRange * 100;
715
- const activeNotes = this.getActiveNotes(channel, now);
716
- activeNotes.forEach((activeNote) => {
717
- const { bufferSource } = activeNote;
718
- const detune = bufferSource.detune.value + detuneChange;
719
- bufferSource.detune
720
- .cancelScheduledValues(now)
721
- .setValueAtTime(detune, now);
722
- });
715
+ this.updateDetune(channel, detuneChange);
723
716
  }
724
717
  handleControlChange(channelNumber, controller, value) {
725
718
  switch (controller) {
@@ -738,9 +731,9 @@ class MidyGM1 {
738
731
  case 64:
739
732
  return this.setSustainPedal(channelNumber, value);
740
733
  case 100:
741
- return this.setRPNMSB(channelNumber, value);
742
- case 101:
743
734
  return this.setRPNLSB(channelNumber, value);
735
+ case 101:
736
+ return this.setRPNMSB(channelNumber, value);
744
737
  case 120:
745
738
  return this.allSoundOff(channelNumber);
746
739
  case 121:
@@ -807,41 +800,62 @@ class MidyGM1 {
807
800
  this.releaseSustainPedal(channelNumber, value);
808
801
  }
809
802
  }
810
- setRPNMSB(channelNumber, value) {
811
- this.channels[channelNumber].rpnMSB = value;
803
+ limitData(channel, minMSB, maxMSB, minLSB, maxLSB) {
804
+ if (maxLSB < channel.dataLSB) {
805
+ channel.dataMSB++;
806
+ channel.dataLSB = minLSB;
807
+ }
808
+ else if (channel.dataLSB < 0) {
809
+ channel.dataMSB--;
810
+ channel.dataLSB = maxLSB;
811
+ }
812
+ if (maxMSB < channel.dataMSB) {
813
+ channel.dataMSB = maxMSB;
814
+ channel.dataLSB = maxLSB;
815
+ }
816
+ else if (channel.dataMSB < 0) {
817
+ channel.dataMSB = minMSB;
818
+ channel.dataLSB = minLSB;
819
+ }
812
820
  }
813
- setRPNLSB(channelNumber, value) {
814
- this.channels[channelNumber].rpnLSB = value;
821
+ limitDataMSB(channel, minMSB, maxMSB) {
822
+ if (maxMSB < channel.dataMSB) {
823
+ channel.dataMSB = maxMSB;
824
+ }
825
+ else if (channel.dataMSB < 0) {
826
+ channel.dataMSB = minMSB;
827
+ }
815
828
  }
816
- setDataEntry(channelNumber, value, isMSB) {
829
+ handleRPN(channelNumber) {
817
830
  const channel = this.channels[channelNumber];
818
831
  const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
819
- isMSB ? channel.dataMSB = value : channel.dataLSB = value;
820
- const { dataMSB, dataLSB } = channel;
821
832
  switch (rpn) {
822
833
  case 0:
823
- return this.handlePitchBendRangeMessage(channelNumber, dataMSB, dataLSB);
834
+ this.handlePitchBendRangeMessage(channelNumber);
835
+ break;
824
836
  case 1:
825
- channel.fineTuning = (dataMSB * 128 + dataLSB - 8192) / 8192;
837
+ this.handleFineTuningMessage(channelNumber);
826
838
  break;
827
839
  case 2:
828
- channel.coarseTuning = dataMSB - 64;
840
+ this.handleCoarseTuningMessage(channelNumber);
829
841
  break;
830
842
  default:
831
843
  console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
832
844
  }
833
845
  }
834
- handlePitchBendRangeMessage(channelNumber, dataMSB, dataLSB) {
835
- const pitchBendRange = dataMSB + dataLSB / 100;
836
- this.setPitchBendRange(channelNumber, pitchBendRange);
846
+ setRPNMSB(channelNumber, value) {
847
+ this.channels[channelNumber].rpnMSB = value;
837
848
  }
838
- setPitchBendRange(channelNumber, pitchBendRange) {
839
- const now = this.audioContext.currentTime;
849
+ setRPNLSB(channelNumber, value) {
850
+ this.channels[channelNumber].rpnLSB = value;
851
+ }
852
+ setDataEntry(channelNumber, value, isMSB) {
840
853
  const channel = this.channels[channelNumber];
841
- const prevPitchBendRange = channel.pitchBendRange;
842
- channel.pitchBendRange = pitchBendRange;
843
- const detuneChange = (channel.pitchBendRange - prevPitchBendRange) *
844
- channel.pitchBend * 100;
854
+ isMSB ? channel.dataMSB = value : channel.dataLSB = value;
855
+ this.handleRPN(channelNumber);
856
+ }
857
+ updateDetune(channel, detuneChange) {
858
+ const now = this.audioContext.currentTime;
845
859
  const activeNotes = this.getActiveNotes(channel, now);
846
860
  activeNotes.forEach((activeNote) => {
847
861
  const { bufferSource } = activeNote;
@@ -851,6 +865,40 @@ class MidyGM1 {
851
865
  .setValueAtTime(detune, now);
852
866
  });
853
867
  }
868
+ handlePitchBendRangeMessage(channelNumber) {
869
+ const channel = this.channels[channelNumber];
870
+ this.limitData(channel, 0, 127, 0, 99);
871
+ const pitchBendRange = channel.dataMSB + channel.dataLSB / 100;
872
+ this.setPitchBendRange(channelNumber, pitchBendRange);
873
+ }
874
+ setPitchBendRange(channelNumber, pitchBendRange) {
875
+ const channel = this.channels[channelNumber];
876
+ const prevPitchBendRange = channel.pitchBendRange;
877
+ channel.pitchBendRange = pitchBendRange;
878
+ const detuneChange = (channel.pitchBendRange - prevPitchBendRange) *
879
+ channel.pitchBend * 100;
880
+ this.updateDetune(channel, detuneChange);
881
+ }
882
+ handleFineTuningMessage(channelNumber) {
883
+ const channel = this.channels[channelNumber];
884
+ this.limitData(channel, 0, 127, 0, 127);
885
+ const fineTuning = (channel.dataMSB * 128 + channel.dataLSB - 8192) / 8192;
886
+ this.setFineTuning(channelNumber, fineTuning);
887
+ }
888
+ setFineTuning(channelNumber, fineTuning) {
889
+ const channel = this.channels[channelNumber];
890
+ channel.fineTuning = fineTuning;
891
+ }
892
+ handleCoarseTuningMessage(channelNumber) {
893
+ const channel = this.channels[channelNumber];
894
+ this.limitDataMSB(channel, 0, 127);
895
+ const coarseTuning = channel.dataMSB - 64;
896
+ this.setFineTuning(channelNumber, coarseTuning);
897
+ }
898
+ setCoarseTuning(channelNumber, coarseTuning) {
899
+ const channel = this.channels[channelNumber];
900
+ channel.fineTuning = coarseTuning;
901
+ }
854
902
  allSoundOff(channelNumber) {
855
903
  const now = this.audioContext.currentTime;
856
904
  const channel = this.channels[channelNumber];
@@ -73,8 +73,8 @@ export class MidyGM2 {
73
73
  lfoFilterDepth: number;
74
74
  lfoAmplitudeDepth: number;
75
75
  };
76
- gainNode: any;
77
- pannerNode: any;
76
+ gainL: any;
77
+ gainR: any;
78
78
  reverbEffect: {
79
79
  convolverNode: any;
80
80
  dryGain: any;
@@ -117,8 +117,8 @@ export class MidyGM2 {
117
117
  loadSoundFont(soundFontUrl: any): Promise<void>;
118
118
  loadMIDI(midiUrl: any): Promise<void>;
119
119
  setChannelAudioNodes(audioContext: any): {
120
- gainNode: any;
121
- pannerNode: any;
120
+ gainL: any;
121
+ gainR: any;
122
122
  reverbEffect: {
123
123
  convolverNode: any;
124
124
  dryGain: any;
@@ -142,8 +142,8 @@ export class MidyGM2 {
142
142
  lfoFilterDepth: number;
143
143
  lfoAmplitudeDepth: number;
144
144
  };
145
- gainNode: any;
146
- pannerNode: any;
145
+ gainL: any;
146
+ gainR: any;
147
147
  reverbEffect: {
148
148
  convolverNode: any;
149
149
  dryGain: any;
@@ -254,11 +254,19 @@ export class MidyGM2 {
254
254
  setChorus(channelNumber: any, chorus: any): void;
255
255
  setSostenutoPedal(channelNumber: any, value: any): void;
256
256
  setSoftPedal(channelNumber: any, softPedal: any): void;
257
+ limitData(channel: any, minMSB: any, maxMSB: any, minLSB: any, maxLSB: any): void;
258
+ limitDataMSB(channel: any, minMSB: any, maxMSB: any): void;
259
+ handleRPN(channelNumber: any, value: any): void;
257
260
  setRPNMSB(channelNumber: any, value: any): void;
258
261
  setRPNLSB(channelNumber: any, value: any): void;
259
262
  setDataEntry(channelNumber: any, value: any, isMSB: any): void;
260
- handlePitchBendRangeMessage(channelNumber: any, dataMSB: any, dataLSB: any): void;
263
+ updateDetune(channel: any, detuneChange: any): void;
264
+ handlePitchBendRangeMessage(channelNumber: any): void;
261
265
  setPitchBendRange(channelNumber: any, pitchBendRange: any): void;
266
+ handleFineTuningMessage(channelNumber: any): void;
267
+ setFineTuning(channelNumber: any, fineTuning: any): void;
268
+ handleCoarseTuningMessage(channelNumber: any): void;
269
+ setCoarseTuning(channelNumber: any, coarseTuning: any): void;
262
270
  allSoundOff(channelNumber: any): any[];
263
271
  resetAllControllers(channelNumber: any): void;
264
272
  allNotesOff(channelNumber: any): any[];
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAuBA;IAwBE;;;;;;;;;;;;;;;;;MAiBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAtED,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;IA4ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;MAoBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAcC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EAkDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgGC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED;;;;MAoCC;IAED;;;;;MAqCC;IAED,sDA2BC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHAiCC;IAED,gDAQC;IAED,kGAgCC;IAED,0EAGC;IAED,sIAoDC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,wFAmBC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,uDAeC;IAED,mFAuDC;IAED,+CAEC;IAED,yDAiBC;IAED,iEAEC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,+CAEC;IAED,sCAUC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAWC;IAED,uDAGC;IAED,gDAEC;IAED,gDAEC;IAED,+DA0BC;IAED,kFAGC;IAED,iEAeC;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,mCAQC;IAED,6CAGC;IAED,2CAMC;IAED,+CAGC;IAED,+CAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAv4CD;IASE,gFAKC;IAbD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
1
+ {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAuBA;IAwBE;;;;;;;;;;;;;;;;;MAiBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAtED,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;IA4ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;MAqBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAcC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EAkDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgGC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED;;;;MAoCC;IAED;;;;;MAqCC;IAED,sDA6BC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHAiCC;IAED,gDAQC;IAED,kGAgCC;IAED,0EAGC;IAED,sIAoDC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,wFAmBC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,uDAOC;IAED,mFAuDC;IAED,+CAEC;IAED,yDAiBC;IAED,iEAEC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,+CAEC;IAED,sCAUC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAWC;IAED,uDAGC;IAED,kFAeC;IAED,2DAMC;IAED,gDAqBC;IAED,gDAEC;IAED,gDAEC;IAED,+DAIC;IAED,oDAUC;IAED,sDAKC;IAED,iEAOC;IAED,kDAKC;IAED,yDAGC;IAED,oDAKC;IAED,6DAGC;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,mCAQC;IAED,6CAGC;IAED,2CAMC;IAED,+CAGC;IAED,+CAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AA17CD;IASE,gFAKC;IAbD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}