@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/esm/midy.js CHANGED
@@ -359,15 +359,15 @@ export class Midy {
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 Midy {
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 Midy {
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(),
@@ -1373,36 +1374,17 @@ export class Midy {
1373
1374
  const pressureDepth = (channel.pressureTable[0] - 64) / 37.5; // 2400 / 64;
1374
1375
  channel.detune += pressureDepth * (next - prev);
1375
1376
  }
1377
+ const table = channel.pressureTable;
1376
1378
  channel.scheduledNotes.forEach((noteList) => {
1377
1379
  for (let i = 0; i < noteList.length; i++) {
1378
1380
  const note = noteList[i];
1379
1381
  if (!note)
1380
1382
  continue;
1381
- this.setChannelPressure(channel, note);
1383
+ this.applyDestinationSettings(channel, note, table);
1382
1384
  }
1383
1385
  });
1384
1386
  // this.applyVoiceParams(channel, 13);
1385
1387
  }
1386
- setChannelPressure(channel, note) {
1387
- if (channel.pressureTable[0] !== 64) {
1388
- this.updateDetune(channel);
1389
- }
1390
- if (channel.pressureTable[1] !== 64 && !note.portamento) {
1391
- this.setFilterEnvelope(channel, note);
1392
- }
1393
- if (channel.pressureTable[2] !== 64 && !note.portamento) {
1394
- this.setVolumeEnvelope(channel, note);
1395
- }
1396
- if (channel.pressureTable[3] !== 0) {
1397
- this.setModLfoToPitch(channel, note);
1398
- }
1399
- if (channel.pressureTable[4] !== 0) {
1400
- this.setModLfoToFilterFc(channel, note);
1401
- }
1402
- if (channel.pressureTable[5] !== 0) {
1403
- this.setModLfoToVolume(channel, note);
1404
- }
1405
- }
1406
1388
  handlePitchBendMessage(channelNumber, lsb, msb) {
1407
1389
  const pitchBend = msb * 128 + lsb;
1408
1390
  this.setPitchBend(channelNumber, pitchBend);
@@ -1544,7 +1526,7 @@ export class Midy {
1544
1526
  this.setModLfoToFilterFc(channel, note);
1545
1527
  }
1546
1528
  },
1547
- modLfoToVolume: (channel, note) => {
1529
+ modLfoToVolume: (channel, note, _prevValue) => {
1548
1530
  if (0 < channel.state.modulationDepth) {
1549
1531
  this.setModLfoToVolume(channel, note);
1550
1532
  }
@@ -1560,12 +1542,12 @@ export class Midy {
1560
1542
  delayVibLFO: (channel, note, prevValue) => {
1561
1543
  if (0 < channel.state.vibratoDepth) {
1562
1544
  const now = this.audioContext.currentTime;
1563
- const prevStartTime = note.startTime +
1564
- prevValue * channel.state.vibratoDelay * 2;
1545
+ const vibratoDelay = channel.state.vibratoDelay * 2;
1546
+ const prevStartTime = note.startTime + prevValue * vibratoDelay;
1565
1547
  if (now < prevStartTime)
1566
1548
  return;
1567
- const startTime = note.startTime +
1568
- value * channel.state.vibratoDelay * 2;
1549
+ const value = note.voiceParams.delayVibLFO;
1550
+ const startTime = note.startTime + value * vibratoDelay;
1569
1551
  note.vibratoLFO.stop(now);
1570
1552
  note.vibratoLFO.start(startTime);
1571
1553
  }
@@ -1573,9 +1555,10 @@ export class Midy {
1573
1555
  freqVibLFO: (channel, note, _prevValue) => {
1574
1556
  if (0 < channel.state.vibratoDepth) {
1575
1557
  const now = this.audioContext.currentTime;
1558
+ const freqVibLFO = note.voiceParams.freqVibLFO;
1576
1559
  note.vibratoLFO.frequency
1577
1560
  .cancelScheduledValues(now)
1578
- .setValueAtTime(value * sate.vibratoRate, now);
1561
+ .setValueAtTime(freqVibLFO * channel.state.vibratoRate, now);
1579
1562
  }
1580
1563
  },
1581
1564
  };
@@ -1682,8 +1665,8 @@ export class Midy {
1682
1665
  if (handler) {
1683
1666
  handler.call(this, channelNumber, value);
1684
1667
  const channel = this.channels[channelNumber];
1685
- const controller = 128 + controllerType;
1686
- this.applyVoiceParams(channel, controller);
1668
+ this.applyVoiceParams(channel, controllerType + 128);
1669
+ this.applyControlTable(channel, controllerType);
1687
1670
  }
1688
1671
  else {
1689
1672
  console.warn(`Unsupported Control change: controllerType=${controllerType} value=${value}`);
@@ -1694,13 +1677,14 @@ export class Midy {
1694
1677
  }
1695
1678
  updateModulation(channel) {
1696
1679
  const now = this.audioContext.currentTime;
1680
+ const depth = channel.state.modulationDepth * channel.modulationDepthRange;
1697
1681
  channel.scheduledNotes.forEach((noteList) => {
1698
1682
  for (let i = 0; i < noteList.length; i++) {
1699
1683
  const note = noteList[i];
1700
1684
  if (!note)
1701
1685
  continue;
1702
1686
  if (note.modulationDepth) {
1703
- note.modulationDepth.gain.setValueAtTime(channel.state.modulationDepth, now);
1687
+ note.modulationDepth.gain.setValueAtTime(depth, now);
1704
1688
  }
1705
1689
  else {
1706
1690
  this.setPitchEnvelope(note);
@@ -1711,8 +1695,7 @@ export class Midy {
1711
1695
  }
1712
1696
  setModulationDepth(channelNumber, modulation) {
1713
1697
  const channel = this.channels[channelNumber];
1714
- channel.state.modulationDepth = (modulation / 127) *
1715
- channel.modulationDepthRange;
1698
+ channel.state.modulationDepth = modulation / 127;
1716
1699
  this.updateModulation(channel);
1717
1700
  }
1718
1701
  setPortamentoTime(channelNumber, portamentoTime) {
@@ -2106,7 +2089,6 @@ export class Midy {
2106
2089
  setModulationDepthRange(channelNumber, modulationDepthRange) {
2107
2090
  const channel = this.channels[channelNumber];
2108
2091
  channel.modulationDepthRange = modulationDepthRange;
2109
- channel.modulationDepth = (modulation / 127) * modulationDepthRange;
2110
2092
  this.updateModulation(channel);
2111
2093
  }
2112
2094
  allSoundOff(channelNumber) {
@@ -2231,9 +2213,8 @@ export class Midy {
2231
2213
  switch (data[3]) {
2232
2214
  case 1: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
2233
2215
  return this.handleChannelPressureSysEx(data);
2234
- // case 3:
2235
- // // TODO
2236
- // return this.setControlChange();
2216
+ case 3: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
2217
+ return this.handleControlChangeSysEx(data);
2237
2218
  default:
2238
2219
  console.warn(`Unsupported Exclusive Message: ${data}`);
2239
2220
  }
@@ -2260,8 +2241,8 @@ export class Midy {
2260
2241
  }
2261
2242
  else {
2262
2243
  const now = this.audioContext.currentTime;
2263
- this.masterGain.gain.cancelScheduledValues(now);
2264
- this.masterGain.gain.setValueAtTime(volume * volume, now);
2244
+ this.masterVolume.gain.cancelScheduledValues(now);
2245
+ this.masterVolume.gain.setValueAtTime(volume * volume, now);
2265
2246
  }
2266
2247
  }
2267
2248
  handleMasterFineTuningSysEx(data) {
@@ -2506,6 +2487,28 @@ export class Midy {
2506
2487
  }
2507
2488
  }
2508
2489
  }
2490
+ applyDestinationSettings(channel, note, table) {
2491
+ if (table[0] !== 64) {
2492
+ this.updateDetune(channel);
2493
+ }
2494
+ if (!note.portamento) {
2495
+ if (table[1] !== 64) {
2496
+ this.setFilterEnvelope(channel, note);
2497
+ }
2498
+ if (table[2] !== 64) {
2499
+ this.setVolumeEnvelope(channel, note);
2500
+ }
2501
+ }
2502
+ if (table[3] !== 0) {
2503
+ this.setModLfoToPitch(channel, note);
2504
+ }
2505
+ if (table[4] !== 0) {
2506
+ this.setModLfoToFilterFc(channel, note);
2507
+ }
2508
+ if (table[5] !== 0) {
2509
+ this.setModLfoToVolume(channel, note);
2510
+ }
2511
+ }
2509
2512
  handleChannelPressureSysEx(data) {
2510
2513
  const channelNumber = data[4];
2511
2514
  const table = this.channels[channelNumber].pressureTable;
@@ -2515,6 +2518,40 @@ export class Midy {
2515
2518
  table[pp] = rr;
2516
2519
  }
2517
2520
  }
2521
+ initControlTable() {
2522
+ const channelCount = 128;
2523
+ const slotSize = 6;
2524
+ const defaultValues = [64, 64, 64, 0, 0, 0];
2525
+ const table = new Uint8Array(channelCount * slotSize);
2526
+ for (let ch = 0; ch < channelCount; ch++) {
2527
+ const offset = ch * slotSize;
2528
+ table.set(defaultValues, offset);
2529
+ }
2530
+ return table;
2531
+ }
2532
+ applyControlTable(channel, controllerType) {
2533
+ const slotSize = 6;
2534
+ const offset = controllerType * slotSize;
2535
+ const table = channel.controlTable.subarray(offset, offset + slotSize);
2536
+ channel.scheduledNotes.forEach((noteList) => {
2537
+ for (let i = 0; i < noteList.length; i++) {
2538
+ const note = noteList[i];
2539
+ if (!note)
2540
+ continue;
2541
+ this.applyDestinationSettings(channel, note, table);
2542
+ }
2543
+ });
2544
+ }
2545
+ handleControlChangeSysEx(data) {
2546
+ const channelNumber = data[4];
2547
+ const controllerType = data[5];
2548
+ const table = this.channels[channelNumber].controlTable[controllerType];
2549
+ for (let i = 6; i < data.length - 1; i += 2) {
2550
+ const pp = data[i];
2551
+ const rr = data[i + 1];
2552
+ table[pp] = rr;
2553
+ }
2554
+ }
2518
2555
  getKeyBasedInstrumentControlValue(channel, keyNumber, controllerType) {
2519
2556
  const index = keyNumber * 128 + controllerType;
2520
2557
  const controlValue = channel.keyBasedInstrumentControlTable[index];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marmooo/midy",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
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",
@@ -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"}
@@ -236,11 +236,11 @@ class MidyGM1 {
236
236
  value: new Map()
237
237
  });
238
238
  this.audioContext = audioContext;
239
- this.masterGain = new GainNode(audioContext);
239
+ this.masterVolume = new GainNode(audioContext);
240
240
  this.voiceParamsHandlers = this.createVoiceParamsHandlers();
241
241
  this.controlChangeHandlers = this.createControlChangeHandlers();
242
242
  this.channels = this.createChannels(audioContext);
243
- this.masterGain.connect(audioContext.destination);
243
+ this.masterVolume.connect(audioContext.destination);
244
244
  this.GM1SystemOn();
245
245
  }
246
246
  initSoundFontTable() {
@@ -286,7 +286,7 @@ class MidyGM1 {
286
286
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
287
287
  gainL.connect(merger, 0, 0);
288
288
  gainR.connect(merger, 0, 1);
289
- merger.connect(this.masterGain);
289
+ merger.connect(this.masterVolume);
290
290
  return {
291
291
  gainL,
292
292
  gainR,
@@ -948,7 +948,7 @@ class MidyGM1 {
948
948
  if (0 < channel.state.modulationDepth)
949
949
  this.setModLfoToFilterFc(note);
950
950
  },
951
- modLfoToVolume: (channel, note) => {
951
+ modLfoToVolume: (channel, note, _prevValue) => {
952
952
  if (0 < channel.state.modulationDepth)
953
953
  this.setModLfoToVolume(note);
954
954
  },
@@ -959,12 +959,12 @@ class MidyGM1 {
959
959
  delayVibLFO: (channel, note, prevValue) => {
960
960
  if (0 < channel.state.vibratoDepth) {
961
961
  const now = this.audioContext.currentTime;
962
- const prevStartTime = note.startTime +
963
- prevValue * channel.state.vibratoDelay * 2;
962
+ const vibratoDelay = channel.state.vibratoDelay * 2;
963
+ const prevStartTime = note.startTime + prevValue * vibratoDelay;
964
964
  if (now < prevStartTime)
965
965
  return;
966
- const startTime = note.startTime +
967
- value * channel.state.vibratoDelay * 2;
966
+ const value = note.voiceParams.delayVibLFO;
967
+ const startTime = note.startTime + value * vibratoDelay;
968
968
  note.vibratoLFO.stop(now);
969
969
  note.vibratoLFO.start(startTime);
970
970
  }
@@ -972,9 +972,10 @@ class MidyGM1 {
972
972
  freqVibLFO: (channel, note, _prevValue) => {
973
973
  if (0 < channel.state.vibratoDepth) {
974
974
  const now = this.audioContext.currentTime;
975
+ const freqVibLFO = note.voiceParams.freqVibLFO;
975
976
  note.vibratoLFO.frequency
976
977
  .cancelScheduledValues(now)
977
- .setValueAtTime(value * sate.vibratoRate, now);
978
+ .setValueAtTime(freqVibLFO * channel.state.vibratoRate, now);
978
979
  }
979
980
  },
980
981
  };
@@ -1053,6 +1054,8 @@ class MidyGM1 {
1053
1054
  const handler = this.controlChangeHandlers[controllerType];
1054
1055
  if (handler) {
1055
1056
  handler.call(this, channelNumber, value);
1057
+ const channel = this.channels[channelNumber];
1058
+ this.applyVoiceParams(channel, controller + 128);
1056
1059
  }
1057
1060
  else {
1058
1061
  console.warn(`Unsupported Control change: controllerType=${controllerType} value=${value}`);
@@ -1060,13 +1063,14 @@ class MidyGM1 {
1060
1063
  }
1061
1064
  updateModulation(channel) {
1062
1065
  const now = this.audioContext.currentTime;
1066
+ const depth = channel.state.modulationDepth * channel.modulationDepthRange;
1063
1067
  channel.scheduledNotes.forEach((noteList) => {
1064
1068
  for (let i = 0; i < noteList.length; i++) {
1065
1069
  const note = noteList[i];
1066
1070
  if (!note)
1067
1071
  continue;
1068
1072
  if (note.modulationDepth) {
1069
- note.modulationDepth.gain.setValueAtTime(channel.state.modulationDepth, now);
1073
+ note.modulationDepth.gain.setValueAtTime(depth, now);
1070
1074
  }
1071
1075
  else {
1072
1076
  this.setPitchEnvelope(note);
@@ -1077,8 +1081,7 @@ class MidyGM1 {
1077
1081
  }
1078
1082
  setModulationDepth(channelNumber, modulation) {
1079
1083
  const channel = this.channels[channelNumber];
1080
- channel.state.modulationDepth = (modulation / 127) *
1081
- channel.modulationDepthRange;
1084
+ channel.state.modulationDepth = modulation / 127;
1082
1085
  this.updateModulation(channel);
1083
1086
  }
1084
1087
  setVolume(channelNumber, volume) {
@@ -1298,8 +1301,8 @@ class MidyGM1 {
1298
1301
  }
1299
1302
  else {
1300
1303
  const now = this.audioContext.currentTime;
1301
- this.masterGain.gain.cancelScheduledValues(now);
1302
- this.masterGain.gain.setValueAtTime(volume * volume, now);
1304
+ this.masterVolume.gain.cancelScheduledValues(now);
1305
+ this.masterVolume.gain.setValueAtTime(volume * volume, now);
1303
1306
  }
1304
1307
  }
1305
1308
  handleExclusiveMessage(data) {
@@ -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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"}