@marmooo/midy 0.2.2 → 0.2.3

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/README.md CHANGED
@@ -1,10 +1,9 @@
1
1
  # Midy
2
2
 
3
- A MIDI player/synthesizer written in JavaScript that supports GM-Lite/GM1 and
4
- SF2/SF3.
3
+ A MIDI player/synthesizer written in JavaScript that supports GM-Lite/GM1/GM2
4
+ and SF2/SF3.
5
5
 
6
- This library provides several files depending on the implementation level. GM2
7
- support is in progress and should be completed soon.
6
+ This library provides several files depending on the implementation level.
8
7
 
9
8
  - midy-GMLite.js: support minimal GM-Lite (ref:
10
9
  [en](https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/gml-v1.pdf),
@@ -16,7 +15,6 @@ support is in progress and should be completed soon.
16
15
  [en v1.2a](https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/GM2-v12a.pdf),
17
16
  [en v1.0](https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp24(e).pdf),
18
17
  [ja v1.0](https://amei.or.jp/midistandardcommittee/Recommended_Practice/GM2_japanese.pdf))
19
- (in progress)
20
18
  - midy.js: full implementation (in progress)
21
19
 
22
20
  ## Usage
package/esm/midy-GM1.d.ts CHANGED
@@ -32,12 +32,12 @@ export class MidyGM1 {
32
32
  notePromises: any[];
33
33
  exclusiveClassMap: Map<any, any>;
34
34
  audioContext: any;
35
- masterGain: any;
35
+ masterVolume: any;
36
36
  voiceParamsHandlers: {
37
37
  modLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
38
38
  vibLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
39
39
  modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
40
- modLfoToVolume: (channel: any, note: any) => void;
40
+ modLfoToVolume: (channel: any, note: any, _prevValue: any) => void;
41
41
  chorusEffectsSend: (_channel: any, _note: any, _prevValue: any) => void;
42
42
  reverbEffectsSend: (_channel: any, _note: any, _prevValue: any) => void;
43
43
  delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
@@ -124,7 +124,7 @@ export class MidyGM1 {
124
124
  modLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
125
125
  vibLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
126
126
  modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
127
- modLfoToVolume: (channel: any, note: any) => void;
127
+ modLfoToVolume: (channel: any, note: any, _prevValue: any) => void;
128
128
  chorusEffectsSend: (_channel: any, _note: any, _prevValue: any) => void;
129
129
  reverbEffectsSend: (_channel: any, _note: any, _prevValue: any) => void;
130
130
  delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqFA;IAoBE;;;;;;;;;;;;MAYE;IAEF,+BAQC;IAzCD,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;IAClB,iCAA8B;IAiB5B,kBAAgC;IAChC,gBAA4C;IAC5C;;;;;;;;;;;MAA2D;IAC3D;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,6DA2BC;IAED,iEAUC;IAED,2EA+CC;IAED,mCAOC;IAED,0BAkDC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgEC;IAED,+EAmBC;IAED,qDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,iCAWC;IAED,mCAgBC;IAED,kCAqBC;IAED,6CAIC;IAED,mCAuBC;IAED,+DAoBC;IAED,gHA2BC;IAED,kGAgDC;IAED,0EAGC;IAED,qFA4BC;IAED,6HAuBC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,mDASC;IAED,gDASC;IAED,gDASC;IAED,qCAMC;IAED,mCAQC;IAED,gCAOC;IAED,+BAMC;IAED;;;;;;;;;;;MA2CC;IAED,oFAMC;IAED,0DA6CC;IAED;;;;;;;;;;;;;MAeC;IAED,+EASC;IAED,qCAiBC;IAED,8DAKC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,wCAWC;IAED,sDAKC;IAED,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,kDAKC;IAED,wDASC;IAED,8CAKC;IAED,oDAOC;IAED,gDAKC;IAED,sDAOC;IAED,+CAEC;IAED,8CAqBC;IAED,+CAEC;IAED,4DAgBC;IAED,oBAMC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAjzCD;IAUE,0FAMC;IAfD,kBAAa;IACb,gBAAW;IACX,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAChB,gBAAW;IACX,kBAAa;IAGX,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
1
+ {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqFA;IAoBE;;;;;;;;;;;;MAYE;IAEF,+BAQC;IAzCD,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;IAClB,iCAA8B;IAiB5B,kBAAgC;IAChC,kBAA8C;IAC9C;;;;;;;;;;;MAA2D;IAC3D;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,6DA2BC;IAED,iEAUC;IAED,2EA+CC;IAED,mCAOC;IAED,0BAkDC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgEC;IAED,+EAmBC;IAED,qDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,iCAWC;IAED,mCAgBC;IAED,kCAqBC;IAED,6CAIC;IAED,mCAuBC;IAED,+DAoBC;IAED,gHA2BC;IAED,kGAgDC;IAED,0EAGC;IAED,qFA4BC;IAED,6HAuBC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,mDASC;IAED,gDASC;IAED,gDASC;IAED,qCAMC;IAED,mCAQC;IAED,gCAOC;IAED,+BAMC;IAED;;;;;;;;;;;MA4CC;IAED,oFAMC;IAED,0DA6CC;IAED;;;;;;;;;;;;;MAeC;IAED,+EAWC;IAED,qCAeC;IAED,8DAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,wCAWC;IAED,sDAKC;IAED,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,kDAKC;IAED,wDASC;IAED,8CAKC;IAED,oDAOC;IAED,gDAKC;IAED,sDAOC;IAED,+CAEC;IAED,8CAqBC;IAED,+CAEC;IAED,4DAgBC;IAED,oBAMC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAjzCD;IAUE,0FAMC;IAfD,kBAAa;IACb,gBAAW;IACX,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAChB,gBAAW;IACX,kBAAa;IAGX,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
package/esm/midy-GM1.js CHANGED
@@ -233,11 +233,11 @@ export class MidyGM1 {
233
233
  value: new Map()
234
234
  });
235
235
  this.audioContext = audioContext;
236
- this.masterGain = new GainNode(audioContext);
236
+ this.masterVolume = new GainNode(audioContext);
237
237
  this.voiceParamsHandlers = this.createVoiceParamsHandlers();
238
238
  this.controlChangeHandlers = this.createControlChangeHandlers();
239
239
  this.channels = this.createChannels(audioContext);
240
- this.masterGain.connect(audioContext.destination);
240
+ this.masterVolume.connect(audioContext.destination);
241
241
  this.GM1SystemOn();
242
242
  }
243
243
  initSoundFontTable() {
@@ -283,7 +283,7 @@ export class MidyGM1 {
283
283
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
284
284
  gainL.connect(merger, 0, 0);
285
285
  gainR.connect(merger, 0, 1);
286
- merger.connect(this.masterGain);
286
+ merger.connect(this.masterVolume);
287
287
  return {
288
288
  gainL,
289
289
  gainR,
@@ -945,7 +945,7 @@ export class MidyGM1 {
945
945
  if (0 < channel.state.modulationDepth)
946
946
  this.setModLfoToFilterFc(note);
947
947
  },
948
- modLfoToVolume: (channel, note) => {
948
+ modLfoToVolume: (channel, note, _prevValue) => {
949
949
  if (0 < channel.state.modulationDepth)
950
950
  this.setModLfoToVolume(note);
951
951
  },
@@ -956,12 +956,12 @@ export class MidyGM1 {
956
956
  delayVibLFO: (channel, note, prevValue) => {
957
957
  if (0 < channel.state.vibratoDepth) {
958
958
  const now = this.audioContext.currentTime;
959
- const prevStartTime = note.startTime +
960
- prevValue * channel.state.vibratoDelay * 2;
959
+ const vibratoDelay = channel.state.vibratoDelay * 2;
960
+ const prevStartTime = note.startTime + prevValue * vibratoDelay;
961
961
  if (now < prevStartTime)
962
962
  return;
963
- const startTime = note.startTime +
964
- value * channel.state.vibratoDelay * 2;
963
+ const value = note.voiceParams.delayVibLFO;
964
+ const startTime = note.startTime + value * vibratoDelay;
965
965
  note.vibratoLFO.stop(now);
966
966
  note.vibratoLFO.start(startTime);
967
967
  }
@@ -969,9 +969,10 @@ export class MidyGM1 {
969
969
  freqVibLFO: (channel, note, _prevValue) => {
970
970
  if (0 < channel.state.vibratoDepth) {
971
971
  const now = this.audioContext.currentTime;
972
+ const freqVibLFO = note.voiceParams.freqVibLFO;
972
973
  note.vibratoLFO.frequency
973
974
  .cancelScheduledValues(now)
974
- .setValueAtTime(value * sate.vibratoRate, now);
975
+ .setValueAtTime(freqVibLFO * channel.state.vibratoRate, now);
975
976
  }
976
977
  },
977
978
  };
@@ -1050,6 +1051,8 @@ export class MidyGM1 {
1050
1051
  const handler = this.controlChangeHandlers[controllerType];
1051
1052
  if (handler) {
1052
1053
  handler.call(this, channelNumber, value);
1054
+ const channel = this.channels[channelNumber];
1055
+ this.applyVoiceParams(channel, controller + 128);
1053
1056
  }
1054
1057
  else {
1055
1058
  console.warn(`Unsupported Control change: controllerType=${controllerType} value=${value}`);
@@ -1057,13 +1060,14 @@ export class MidyGM1 {
1057
1060
  }
1058
1061
  updateModulation(channel) {
1059
1062
  const now = this.audioContext.currentTime;
1063
+ const depth = channel.state.modulationDepth * channel.modulationDepthRange;
1060
1064
  channel.scheduledNotes.forEach((noteList) => {
1061
1065
  for (let i = 0; i < noteList.length; i++) {
1062
1066
  const note = noteList[i];
1063
1067
  if (!note)
1064
1068
  continue;
1065
1069
  if (note.modulationDepth) {
1066
- note.modulationDepth.gain.setValueAtTime(channel.state.modulationDepth, now);
1070
+ note.modulationDepth.gain.setValueAtTime(depth, now);
1067
1071
  }
1068
1072
  else {
1069
1073
  this.setPitchEnvelope(note);
@@ -1074,8 +1078,7 @@ export class MidyGM1 {
1074
1078
  }
1075
1079
  setModulationDepth(channelNumber, modulation) {
1076
1080
  const channel = this.channels[channelNumber];
1077
- channel.state.modulationDepth = (modulation / 127) *
1078
- channel.modulationDepthRange;
1081
+ channel.state.modulationDepth = modulation / 127;
1079
1082
  this.updateModulation(channel);
1080
1083
  }
1081
1084
  setVolume(channelNumber, volume) {
@@ -1295,8 +1298,8 @@ export class MidyGM1 {
1295
1298
  }
1296
1299
  else {
1297
1300
  const now = this.audioContext.currentTime;
1298
- this.masterGain.gain.cancelScheduledValues(now);
1299
- this.masterGain.gain.setValueAtTime(volume * volume, now);
1301
+ this.masterVolume.gain.cancelScheduledValues(now);
1302
+ this.masterVolume.gain.setValueAtTime(volume * volume, now);
1300
1303
  }
1301
1304
  }
1302
1305
  handleExclusiveMessage(data) {
package/esm/midy-GM2.d.ts CHANGED
@@ -77,12 +77,12 @@ export class MidyGM2 {
77
77
  output: any;
78
78
  };
79
79
  };
80
- masterGain: any;
80
+ masterVolume: any;
81
81
  voiceParamsHandlers: {
82
82
  modLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
83
83
  vibLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
84
84
  modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
85
- modLfoToVolume: (channel: any, note: any) => void;
85
+ modLfoToVolume: (channel: any, note: any, _prevValue: any) => void;
86
86
  chorusEffectsSend: (channel: any, note: any, prevValue: any) => void;
87
87
  reverbEffectsSend: (channel: any, note: any, prevValue: any) => void;
88
88
  delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
@@ -228,7 +228,7 @@ export class MidyGM2 {
228
228
  modLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
229
229
  vibLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
230
230
  modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
231
- modLfoToVolume: (channel: any, note: any) => void;
231
+ modLfoToVolume: (channel: any, note: any, _prevValue: any) => void;
232
232
  chorusEffectsSend: (channel: any, note: any, prevValue: any) => void;
233
233
  reverbEffectsSend: (channel: any, note: any, prevValue: any) => void;
234
234
  delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
@@ -338,7 +338,11 @@ export class MidyGM2 {
338
338
  getChorusSendToReverb(value: any): number;
339
339
  getChannelBitmap(data: any): any[];
340
340
  handleScaleOctaveTuning1ByteFormatSysEx(data: any): void;
341
+ applyDestinationSettings(channel: any, note: any, table: any): void;
341
342
  handleChannelPressureSysEx(data: any): void;
343
+ initControlTable(): Uint8Array<ArrayBuffer>;
344
+ applyControlTable(channel: any, controllerType: any): void;
345
+ handleControlChangeSysEx(data: any): void;
342
346
  getKeyBasedInstrumentControlValue(channel: any, keyNumber: any, controllerType: any): number;
343
347
  handleKeyBasedInstrumentControlSysEx(data: any): void;
344
348
  handleExclusiveMessage(data: 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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"}
package/esm/midy-GM2.js CHANGED
@@ -359,15 +359,15 @@ export class MidyGM2 {
359
359
  });
360
360
  this.audioContext = audioContext;
361
361
  this.options = { ...this.defaultOptions, ...options };
362
- this.masterGain = new GainNode(audioContext);
362
+ this.masterVolume = new GainNode(audioContext);
363
363
  this.voiceParamsHandlers = this.createVoiceParamsHandlers();
364
364
  this.controlChangeHandlers = this.createControlChangeHandlers();
365
365
  this.channels = this.createChannels(audioContext);
366
366
  this.reverbEffect = this.options.reverbAlgorithm(audioContext);
367
367
  this.chorusEffect = this.createChorusEffect(audioContext);
368
- this.chorusEffect.output.connect(this.masterGain);
369
- this.reverbEffect.output.connect(this.masterGain);
370
- this.masterGain.connect(audioContext.destination);
368
+ this.chorusEffect.output.connect(this.masterVolume);
369
+ this.reverbEffect.output.connect(this.masterVolume);
370
+ this.masterVolume.connect(audioContext.destination);
371
371
  this.GM2SystemOn();
372
372
  }
373
373
  initSoundFontTable() {
@@ -413,7 +413,7 @@ export class MidyGM2 {
413
413
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
414
414
  gainL.connect(merger, 0, 0);
415
415
  gainR.connect(merger, 0, 1);
416
- merger.connect(this.masterGain);
416
+ merger.connect(this.masterVolume);
417
417
  return {
418
418
  gainL,
419
419
  gainR,
@@ -425,6 +425,7 @@ export class MidyGM2 {
425
425
  return {
426
426
  ...this.constructor.channelSettings,
427
427
  state: new ControllerState(),
428
+ controlTable: this.initControlTable(),
428
429
  ...this.setChannelAudioNodes(audioContext),
429
430
  scheduledNotes: new Map(),
430
431
  sostenutoNotes: new Map(),
@@ -1347,12 +1348,13 @@ export class MidyGM2 {
1347
1348
  const pressureDepth = (channel.pressureTable[0] - 64) / 37.5; // 2400 / 64;
1348
1349
  channel.detune += pressureDepth * (next - prev);
1349
1350
  }
1351
+ const table = channel.pressureTable;
1350
1352
  channel.scheduledNotes.forEach((noteList) => {
1351
1353
  for (let i = 0; i < noteList.length; i++) {
1352
1354
  const note = noteList[i];
1353
1355
  if (!note)
1354
1356
  continue;
1355
- this.setChannelPressure(channel, note);
1357
+ this.applyDestinationSettings(channel, note, table);
1356
1358
  }
1357
1359
  });
1358
1360
  // this.applyVoiceParams(channel, 13);
@@ -1361,11 +1363,13 @@ export class MidyGM2 {
1361
1363
  if (channel.pressureTable[0] !== 64) {
1362
1364
  this.updateDetune(channel);
1363
1365
  }
1364
- if (channel.pressureTable[1] !== 64 && !note.portamento) {
1365
- this.setFilterEnvelope(channel, note);
1366
- }
1367
- if (channel.pressureTable[2] !== 64 && !note.portamento) {
1368
- this.setVolumeEnvelope(channel, note);
1366
+ if (!note.portamento) {
1367
+ if (channel.pressureTable[1] !== 64) {
1368
+ this.setFilterEnvelope(channel, note);
1369
+ }
1370
+ if (channel.pressureTable[2] !== 64) {
1371
+ this.setVolumeEnvelope(channel, note);
1372
+ }
1369
1373
  }
1370
1374
  if (channel.pressureTable[3] !== 0) {
1371
1375
  this.setModLfoToPitch(channel, note);
@@ -1518,7 +1522,7 @@ export class MidyGM2 {
1518
1522
  this.setModLfoToFilterFc(channel, note);
1519
1523
  }
1520
1524
  },
1521
- modLfoToVolume: (channel, note) => {
1525
+ modLfoToVolume: (channel, note, _prevValue) => {
1522
1526
  if (0 < channel.state.modulationDepth) {
1523
1527
  this.setModLfoToVolume(channel, note);
1524
1528
  }
@@ -1534,12 +1538,12 @@ export class MidyGM2 {
1534
1538
  delayVibLFO: (channel, note, prevValue) => {
1535
1539
  if (0 < channel.state.vibratoDepth) {
1536
1540
  const now = this.audioContext.currentTime;
1537
- const prevStartTime = note.startTime +
1538
- prevValue * channel.state.vibratoDelay * 2;
1541
+ const vibratoDelay = channel.state.vibratoDelay * 2;
1542
+ const prevStartTime = note.startTime + prevValue * vibratoDelay;
1539
1543
  if (now < prevStartTime)
1540
1544
  return;
1541
- const startTime = note.startTime +
1542
- value * channel.state.vibratoDelay * 2;
1545
+ const value = note.voiceParams.delayVibLFO;
1546
+ const startTime = note.startTime + value * vibratoDelay;
1543
1547
  note.vibratoLFO.stop(now);
1544
1548
  note.vibratoLFO.start(startTime);
1545
1549
  }
@@ -1547,9 +1551,10 @@ export class MidyGM2 {
1547
1551
  freqVibLFO: (channel, note, _prevValue) => {
1548
1552
  if (0 < channel.state.vibratoDepth) {
1549
1553
  const now = this.audioContext.currentTime;
1554
+ const freqVibLFO = note.voiceParams.freqVibLFO;
1550
1555
  note.vibratoLFO.frequency
1551
1556
  .cancelScheduledValues(now)
1552
- .setValueAtTime(value * sate.vibratoRate, now);
1557
+ .setValueAtTime(freqVibLFO * channel.state.vibratoRate, now);
1553
1558
  }
1554
1559
  },
1555
1560
  };
@@ -1646,8 +1651,8 @@ export class MidyGM2 {
1646
1651
  if (handler) {
1647
1652
  handler.call(this, channelNumber, value);
1648
1653
  const channel = this.channels[channelNumber];
1649
- const controller = 128 + controllerType;
1650
- this.applyVoiceParams(channel, controller);
1654
+ this.applyVoiceParams(channel, controller + 128);
1655
+ this.applyControlTable(channel, controllerType);
1651
1656
  }
1652
1657
  else {
1653
1658
  console.warn(`Unsupported Control change: controllerType=${controllerType} value=${value}`);
@@ -1658,13 +1663,14 @@ export class MidyGM2 {
1658
1663
  }
1659
1664
  updateModulation(channel) {
1660
1665
  const now = this.audioContext.currentTime;
1666
+ const depth = channel.state.modulationDepth * channel.modulationDepthRange;
1661
1667
  channel.scheduledNotes.forEach((noteList) => {
1662
1668
  for (let i = 0; i < noteList.length; i++) {
1663
1669
  const note = noteList[i];
1664
1670
  if (!note)
1665
1671
  continue;
1666
1672
  if (note.modulationDepth) {
1667
- note.modulationDepth.gain.setValueAtTime(channel.state.modulationDepth, now);
1673
+ note.modulationDepth.gain.setValueAtTime(depth, now);
1668
1674
  }
1669
1675
  else {
1670
1676
  this.setPitchEnvelope(note);
@@ -1675,8 +1681,7 @@ export class MidyGM2 {
1675
1681
  }
1676
1682
  setModulationDepth(channelNumber, modulation) {
1677
1683
  const channel = this.channels[channelNumber];
1678
- channel.state.modulationDepth = (modulation / 127) *
1679
- channel.modulationDepthRange;
1684
+ channel.state.modulationDepth = modulation / 127;
1680
1685
  this.updateModulation(channel);
1681
1686
  }
1682
1687
  setPortamentoTime(channelNumber, portamentoTime) {
@@ -1979,7 +1984,6 @@ export class MidyGM2 {
1979
1984
  setModulationDepthRange(channelNumber, modulationDepthRange) {
1980
1985
  const channel = this.channels[channelNumber];
1981
1986
  channel.modulationDepthRange = modulationDepthRange;
1982
- channel.modulationDepth = (modulation / 127) * modulationDepthRange;
1983
1987
  this.updateModulation(channel);
1984
1988
  }
1985
1989
  allSoundOff(channelNumber) {
@@ -2095,9 +2099,8 @@ export class MidyGM2 {
2095
2099
  switch (data[3]) {
2096
2100
  case 1: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
2097
2101
  return this.handleChannelPressureSysEx(data);
2098
- // case 3:
2099
- // // TODO
2100
- // return this.setControlChange();
2102
+ case 3: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
2103
+ return this.handleControlChangeSysEx(data);
2101
2104
  default:
2102
2105
  console.warn(`Unsupported Exclusive Message: ${data}`);
2103
2106
  }
@@ -2124,8 +2127,8 @@ export class MidyGM2 {
2124
2127
  }
2125
2128
  else {
2126
2129
  const now = this.audioContext.currentTime;
2127
- this.masterGain.gain.cancelScheduledValues(now);
2128
- this.masterGain.gain.setValueAtTime(volume * volume, now);
2130
+ this.masterVolume.gain.cancelScheduledValues(now);
2131
+ this.masterVolume.gain.setValueAtTime(volume * volume, now);
2129
2132
  }
2130
2133
  }
2131
2134
  handleMasterFineTuningSysEx(data) {
@@ -2370,6 +2373,28 @@ export class MidyGM2 {
2370
2373
  }
2371
2374
  }
2372
2375
  }
2376
+ applyDestinationSettings(channel, note, table) {
2377
+ if (table[0] !== 64) {
2378
+ this.updateDetune(channel);
2379
+ }
2380
+ if (!note.portamento) {
2381
+ if (table[1] !== 64) {
2382
+ this.setFilterEnvelope(channel, note);
2383
+ }
2384
+ if (table[2] !== 64) {
2385
+ this.setVolumeEnvelope(channel, note);
2386
+ }
2387
+ }
2388
+ if (table[3] !== 0) {
2389
+ this.setModLfoToPitch(channel, note);
2390
+ }
2391
+ if (table[4] !== 0) {
2392
+ this.setModLfoToFilterFc(channel, note);
2393
+ }
2394
+ if (table[5] !== 0) {
2395
+ this.setModLfoToVolume(channel, note);
2396
+ }
2397
+ }
2373
2398
  handleChannelPressureSysEx(data) {
2374
2399
  const channelNumber = data[4];
2375
2400
  const table = this.channels[channelNumber].pressureTable;
@@ -2379,6 +2404,40 @@ export class MidyGM2 {
2379
2404
  table[pp] = rr;
2380
2405
  }
2381
2406
  }
2407
+ initControlTable() {
2408
+ const channelCount = 128;
2409
+ const slotSize = 6;
2410
+ const defaultValues = [64, 64, 64, 0, 0, 0];
2411
+ const table = new Uint8Array(channelCount * slotSize);
2412
+ for (let ch = 0; ch < channelCount; ch++) {
2413
+ const offset = ch * slotSize;
2414
+ table.set(defaultValues, offset);
2415
+ }
2416
+ return table;
2417
+ }
2418
+ applyControlTable(channel, controllerType) {
2419
+ const slotSize = 6;
2420
+ const offset = controllerType * slotSize;
2421
+ const table = channel.controlTable.subarray(offset, offset + slotSize);
2422
+ channel.scheduledNotes.forEach((noteList) => {
2423
+ for (let i = 0; i < noteList.length; i++) {
2424
+ const note = noteList[i];
2425
+ if (!note)
2426
+ continue;
2427
+ this.applyDestinationSettings(channel, note, table);
2428
+ }
2429
+ });
2430
+ }
2431
+ handleControlChangeSysEx(data) {
2432
+ const channelNumber = data[4];
2433
+ const controllerType = data[5];
2434
+ const table = this.channels[channelNumber].controlTable[controllerType];
2435
+ for (let i = 6; i < data.length - 1; i += 2) {
2436
+ const pp = data[i];
2437
+ const rr = data[i + 1];
2438
+ table[pp] = rr;
2439
+ }
2440
+ }
2382
2441
  getKeyBasedInstrumentControlValue(channel, keyNumber, controllerType) {
2383
2442
  const index = keyNumber * 128 + controllerType;
2384
2443
  const controlValue = channel.keyBasedInstrumentControlTable[index];
@@ -29,12 +29,12 @@ export class MidyGMLite {
29
29
  notePromises: any[];
30
30
  exclusiveClassMap: Map<any, any>;
31
31
  audioContext: any;
32
- masterGain: any;
32
+ masterVolume: any;
33
33
  voiceParamsHandlers: {
34
34
  modLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
35
35
  vibLfoToPitch: (_channel: any, _note: any, _prevValue: any) => void;
36
36
  modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
37
- modLfoToVolume: (channel: any, note: any) => void;
37
+ modLfoToVolume: (channel: any, note: any, _prevValue: any) => void;
38
38
  chorusEffectsSend: (_channel: any, _note: any, _prevValue: any) => void;
39
39
  reverbEffectsSend: (_channel: any, _note: any, _prevValue: any) => void;
40
40
  delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
@@ -120,7 +120,7 @@ export class MidyGMLite {
120
120
  modLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
121
121
  vibLfoToPitch: (_channel: any, _note: any, _prevValue: any) => void;
122
122
  modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
123
- modLfoToVolume: (channel: any, note: any) => void;
123
+ modLfoToVolume: (channel: any, note: any, _prevValue: any) => void;
124
124
  chorusEffectsSend: (_channel: any, _note: any, _prevValue: any) => void;
125
125
  reverbEffectsSend: (_channel: any, _note: any, _prevValue: any) => void;
126
126
  delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAmFA;IAoBE;;;;;;;;;MASE;IAEF,+BAQC;IAtCD,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;IAClB,iCAA8B;IAc5B,kBAAgC;IAChC,gBAA4C;IAC5C;;;;;;;;;;;MAA2D;IAC3D;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,6DA2BC;IAED,iEAUC;IAED,2EA+CC;IAED,mCAOC;IAED,0BAkDC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgEC;IAED,+EAmBC;IAED,qDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,wCAIC;IAED,iCAWC;IAED,mCAgBC;IAED,kCAqBC;IAED,6CAIC;IAED,mCAuBC;IAED,+DAoBC;IAED,gHA2BC;IAED,kGAgDC;IAED,0EAGC;IAED,qFAwBC;IAED,6HAuBC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,mDASC;IAED,gDASC;IAED,qCAMC;IAED,mCAQC;IAED,gCAOC;IAED,+BAMC;IAED;;;;;;;;;;;MAqBC;IAED,oFAMC;IAED,0DA6CC;IAED;;;;;;;;;;;;;MAeC;IAED,+EASC;IAED,qCAiBC;IAED,8DAKC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,wCAWC;IAED,sDAKC;IAED,kFAeC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,kDAKC;IAED,wEAOC;IAED,+CAEC;IAED,8CAqBC;IAED,+CAEC;IAED,4DAgBC;IAED,oBAMC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AArtCD;IAQE,0FAMC;IAbD,kBAAa;IACb,gBAAW;IACX,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
1
+ {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAmFA;IAoBE;;;;;;;;;MASE;IAEF,+BAQC;IAtCD,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;IAClB,iCAA8B;IAc5B,kBAAgC;IAChC,kBAA8C;IAC9C;;;;;;;;;;;MAA2D;IAC3D;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,6DA2BC;IAED,iEAUC;IAED,2EA+CC;IAED,mCAOC;IAED,0BAkDC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgEC;IAED,+EAmBC;IAED,qDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,wCAIC;IAED,iCAWC;IAED,mCAgBC;IAED,kCAqBC;IAED,6CAIC;IAED,mCAuBC;IAED,+DAoBC;IAED,gHA2BC;IAED,kGAgDC;IAED,0EAGC;IAED,qFAwBC;IAED,6HAuBC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,mDASC;IAED,gDASC;IAED,qCAMC;IAED,mCAQC;IAED,gCAOC;IAED,+BAMC;IAED;;;;;;;;;;;MAqBC;IAED,oFAMC;IAED,0DA6CC;IAED;;;;;;;;;;;;;MAeC;IAED,+EAWC;IAED,qCAeC;IAED,8DAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,wCAWC;IAED,sDAKC;IAED,kFAeC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,kDAKC;IAED,wEAOC;IAED,+CAEC;IAED,8CAqBC;IAED,+CAEC;IAED,4DAgBC;IAED,oBAMC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAptCD;IAQE,0FAMC;IAbD,kBAAa;IACb,gBAAW;IACX,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
@@ -221,11 +221,11 @@ export class MidyGMLite {
221
221
  value: new Map()
222
222
  });
223
223
  this.audioContext = audioContext;
224
- this.masterGain = new GainNode(audioContext);
224
+ this.masterVolume = new GainNode(audioContext);
225
225
  this.voiceParamsHandlers = this.createVoiceParamsHandlers();
226
226
  this.controlChangeHandlers = this.createControlChangeHandlers();
227
227
  this.channels = this.createChannels(audioContext);
228
- this.masterGain.connect(audioContext.destination);
228
+ this.masterVolume.connect(audioContext.destination);
229
229
  this.GM1SystemOn();
230
230
  }
231
231
  initSoundFontTable() {
@@ -271,7 +271,7 @@ export class MidyGMLite {
271
271
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
272
272
  gainL.connect(merger, 0, 0);
273
273
  gainR.connect(merger, 0, 1);
274
- merger.connect(this.masterGain);
274
+ merger.connect(this.masterVolume);
275
275
  return {
276
276
  gainL,
277
277
  gainR,
@@ -913,7 +913,7 @@ export class MidyGMLite {
913
913
  if (0 < channel.state.modulationDepth)
914
914
  this.setModLfoToFilterFc(note);
915
915
  },
916
- modLfoToVolume: (channel, note) => {
916
+ modLfoToVolume: (channel, note, _prevValue) => {
917
917
  if (0 < channel.state.modulationDepth)
918
918
  this.setModLfoToVolume(note);
919
919
  },
@@ -999,6 +999,8 @@ export class MidyGMLite {
999
999
  const handler = this.controlChangeHandlers[controllerType];
1000
1000
  if (handler) {
1001
1001
  handler.call(this, channelNumber, value);
1002
+ const channel = this.channels[channelNumber];
1003
+ this.applyVoiceParams(channel, controller + 128);
1002
1004
  }
1003
1005
  else {
1004
1006
  console.warn(`Unsupported Control change: controllerType=${controllerType} value=${value}`);
@@ -1006,13 +1008,14 @@ export class MidyGMLite {
1006
1008
  }
1007
1009
  updateModulation(channel) {
1008
1010
  const now = this.audioContext.currentTime;
1011
+ const depth = channel.state.modulationDepth * channel.modulationDepthRange;
1009
1012
  channel.scheduledNotes.forEach((noteList) => {
1010
1013
  for (let i = 0; i < noteList.length; i++) {
1011
1014
  const note = noteList[i];
1012
1015
  if (!note)
1013
1016
  continue;
1014
1017
  if (note.modulationDepth) {
1015
- note.modulationDepth.gain.setValueAtTime(channel.state.modulationDepth, now);
1018
+ note.modulationDepth.gain.setValueAtTime(depth, now);
1016
1019
  }
1017
1020
  else {
1018
1021
  this.setPitchEnvelope(note);
@@ -1023,8 +1026,7 @@ export class MidyGMLite {
1023
1026
  }
1024
1027
  setModulationDepth(channelNumber, modulation) {
1025
1028
  const channel = this.channels[channelNumber];
1026
- channel.state.modulationDepth = (modulation / 127) *
1027
- channel.modulationDepthRange;
1029
+ channel.state.modulationDepth = modulation / 127;
1028
1030
  this.updateModulation(channel);
1029
1031
  }
1030
1032
  setVolume(channelNumber, volume) {
@@ -1200,8 +1202,8 @@ export class MidyGMLite {
1200
1202
  }
1201
1203
  else {
1202
1204
  const now = this.audioContext.currentTime;
1203
- this.masterGain.gain.cancelScheduledValues(now);
1204
- this.masterGain.gain.setValueAtTime(volume * volume, now);
1205
+ this.masterVolume.gain.cancelScheduledValues(now);
1206
+ this.masterVolume.gain.setValueAtTime(volume * volume, now);
1205
1207
  }
1206
1208
  }
1207
1209
  handleExclusiveMessage(data) {
package/esm/midy.d.ts CHANGED
@@ -77,12 +77,12 @@ export class Midy {
77
77
  output: any;
78
78
  };
79
79
  };
80
- masterGain: any;
80
+ masterVolume: any;
81
81
  voiceParamsHandlers: {
82
82
  modLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
83
83
  vibLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
84
84
  modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
85
- modLfoToVolume: (channel: any, note: any) => void;
85
+ modLfoToVolume: (channel: any, note: any, _prevValue: any) => void;
86
86
  chorusEffectsSend: (channel: any, note: any, prevValue: any) => void;
87
87
  reverbEffectsSend: (channel: any, note: any, prevValue: any) => void;
88
88
  delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
@@ -224,7 +224,6 @@ export class Midy {
224
224
  handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
225
225
  handleProgramChange(channelNumber: any, program: any): void;
226
226
  handleChannelPressure(channelNumber: any, value: any): void;
227
- setChannelPressure(channel: any, note: any): void;
228
227
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
229
228
  setPitchBend(channelNumber: any, value: any): void;
230
229
  setModLfoToPitch(channel: any, note: any): void;
@@ -239,7 +238,7 @@ export class Midy {
239
238
  modLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
240
239
  vibLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
241
240
  modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
242
- modLfoToVolume: (channel: any, note: any) => void;
241
+ modLfoToVolume: (channel: any, note: any, _prevValue: any) => void;
243
242
  chorusEffectsSend: (channel: any, note: any, prevValue: any) => void;
244
243
  reverbEffectsSend: (channel: any, note: any, prevValue: any) => void;
245
244
  delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
@@ -369,7 +368,11 @@ export class Midy {
369
368
  getChorusSendToReverb(value: any): number;
370
369
  getChannelBitmap(data: any): any[];
371
370
  handleScaleOctaveTuning1ByteFormatSysEx(data: any): void;
371
+ applyDestinationSettings(channel: any, note: any, table: any): void;
372
372
  handleChannelPressureSysEx(data: any): void;
373
+ initControlTable(): Uint8Array<ArrayBuffer>;
374
+ applyControlTable(channel: any, controllerType: any): void;
375
+ handleControlChangeSysEx(data: any): void;
373
376
  getKeyBasedInstrumentControlValue(channel: any, keyNumber: any, controllerType: any): number;
374
377
  handleKeyBasedInstrumentControlSysEx(data: any): void;
375
378
  handleExclusiveMessage(data: any): void;
package/esm/midy.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}