@marmooo/midy 0.1.6 → 0.1.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.
Files changed (37) hide show
  1. package/esm/midy-GM1.d.ts +5 -4
  2. package/esm/midy-GM1.d.ts.map +1 -1
  3. package/esm/midy-GM1.js +45 -16
  4. package/esm/midy-GM2.d.ts +5 -2
  5. package/esm/midy-GM2.d.ts.map +1 -1
  6. package/esm/midy-GM2.js +176 -66
  7. package/esm/midy-GMLite.d.ts +5 -4
  8. package/esm/midy-GMLite.d.ts.map +1 -1
  9. package/esm/midy-GMLite.js +45 -16
  10. package/esm/midy.d.ts +5 -2
  11. package/esm/midy.d.ts.map +1 -1
  12. package/esm/midy.js +177 -67
  13. package/package.json +5 -1
  14. package/script/midy-GM1.d.ts +5 -4
  15. package/script/midy-GM1.d.ts.map +1 -1
  16. package/script/midy-GM1.js +48 -19
  17. package/script/midy-GM2.d.ts +5 -2
  18. package/script/midy-GM2.d.ts.map +1 -1
  19. package/script/midy-GM2.js +179 -69
  20. package/script/midy-GMLite.d.ts +5 -4
  21. package/script/midy-GMLite.d.ts.map +1 -1
  22. package/script/midy-GMLite.js +48 -19
  23. package/script/midy.d.ts +5 -2
  24. package/script/midy.d.ts.map +1 -1
  25. package/script/midy.js +180 -70
  26. package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts +0 -149
  27. package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +0 -1
  28. package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +0 -180
  29. package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts +0 -84
  30. package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts.map +0 -1
  31. package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js +0 -216
  32. package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts +0 -149
  33. package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +0 -1
  34. package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +0 -190
  35. package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts +0 -84
  36. package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts.map +0 -1
  37. package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js +0 -221
package/script/midy.d.ts CHANGED
@@ -83,6 +83,7 @@ export class Midy {
83
83
  timeline: any[];
84
84
  instruments: any[];
85
85
  notePromises: any[];
86
+ exclusiveClassMap: Map<any, any>;
86
87
  defaultOptions: {
87
88
  reverbAlgorithm: (audioContext: any) => {
88
89
  input: any;
@@ -218,8 +219,8 @@ export class Midy {
218
219
  calcBank(channel: any, channelNumber: any): any;
219
220
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
220
221
  noteOn(channelNumber: any, noteNumber: any, velocity: any, portamento: any): Promise<void>;
221
- stopNote(stopTime: any, endTime: any, scheduledNotes: any, index: any): Promise<any>;
222
- scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
222
+ stopNote(endTime: any, stopTime: any, scheduledNotes: any, index: any): Promise<any>;
223
+ scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
223
224
  releaseNote(channelNumber: any, noteNumber: any, velocity: any, portamentoNoteNumber: any): Promise<any> | undefined;
224
225
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
225
226
  releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
@@ -360,6 +361,8 @@ declare class Note {
360
361
  modulationDepth: any;
361
362
  vibratoLFO: any;
362
363
  vibratoDepth: any;
364
+ reverbEffectsSend: any;
365
+ chorusEffectsSend: any;
363
366
  noteNumber: any;
364
367
  velocity: any;
365
368
  startTime: any;
@@ -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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"}
package/script/midy.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Midy = void 0;
4
- const _esm_js_1 = require("./deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js");
5
- const _esm_js_2 = require("./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js");
4
+ const midi_file_1 = require("midi-file");
5
+ const soundfont_parser_1 = require("@marmooo/soundfont-parser");
6
6
  class Note {
7
7
  constructor(noteNumber, velocity, startTime, instrumentKey) {
8
8
  Object.defineProperty(this, "bufferSource", {
@@ -53,6 +53,18 @@ class Note {
53
53
  writable: true,
54
54
  value: void 0
55
55
  });
56
+ Object.defineProperty(this, "reverbEffectsSend", {
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true,
60
+ value: void 0
61
+ });
62
+ Object.defineProperty(this, "chorusEffectsSend", {
63
+ enumerable: true,
64
+ configurable: true,
65
+ writable: true,
66
+ value: void 0
67
+ });
56
68
  this.noteNumber = noteNumber;
57
69
  this.velocity = velocity;
58
70
  this.startTime = startTime;
@@ -208,6 +220,12 @@ class Midy {
208
220
  writable: true,
209
221
  value: []
210
222
  });
223
+ Object.defineProperty(this, "exclusiveClassMap", {
224
+ enumerable: true,
225
+ configurable: true,
226
+ writable: true,
227
+ value: new Map()
228
+ });
211
229
  Object.defineProperty(this, "defaultOptions", {
212
230
  enumerable: true,
213
231
  configurable: true,
@@ -264,14 +282,14 @@ class Midy {
264
282
  async loadSoundFont(soundFontUrl) {
265
283
  const response = await fetch(soundFontUrl);
266
284
  const arrayBuffer = await response.arrayBuffer();
267
- const parsed = (0, _esm_js_2.parse)(new Uint8Array(arrayBuffer));
268
- const soundFont = new _esm_js_2.SoundFont(parsed);
285
+ const parsed = (0, soundfont_parser_1.parse)(new Uint8Array(arrayBuffer));
286
+ const soundFont = new soundfont_parser_1.SoundFont(parsed);
269
287
  this.addSoundFont(soundFont);
270
288
  }
271
289
  async loadMIDI(midiUrl) {
272
290
  const response = await fetch(midiUrl);
273
291
  const arrayBuffer = await response.arrayBuffer();
274
- const midi = (0, _esm_js_1.parseMidi)(new Uint8Array(arrayBuffer));
292
+ const midi = (0, midi_file_1.parseMidi)(new Uint8Array(arrayBuffer));
275
293
  this.ticksPerBeat = midi.header.ticksPerBeat;
276
294
  const midiData = this.extractMidiData(midi);
277
295
  this.instruments = midiData.instruments;
@@ -314,19 +332,25 @@ class Midy {
314
332
  const sampleStart = instrumentKey.start;
315
333
  const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
316
334
  if (isSF3) {
317
- const sample = instrumentKey.sample.slice(sampleStart, sampleEnd);
318
- const audioBuffer = await this.audioContext.decodeAudioData(sample.buffer);
335
+ const sample = instrumentKey.sample;
336
+ const start = sample.byteOffset + sampleStart;
337
+ const end = sample.byteOffset + sampleEnd;
338
+ const buffer = sample.buffer.slice(start, end);
339
+ const audioBuffer = await this.audioContext.decodeAudioData(buffer);
319
340
  return audioBuffer;
320
341
  }
321
342
  else {
322
- const sample = instrumentKey.sample.subarray(sampleStart, sampleEnd);
343
+ const sample = instrumentKey.sample;
344
+ const start = sample.byteOffset + sampleStart;
345
+ const end = sample.byteOffset + sampleEnd;
346
+ const buffer = sample.buffer.slice(start, end);
323
347
  const audioBuffer = new AudioBuffer({
324
348
  numberOfChannels: 1,
325
349
  length: sample.length,
326
350
  sampleRate: instrumentKey.sampleRate,
327
351
  });
328
352
  const channelData = audioBuffer.getChannelData(0);
329
- const int16Array = new Int16Array(sample.buffer);
353
+ const int16Array = new Int16Array(buffer);
330
354
  for (let i = 0; i < int16Array.length; i++) {
331
355
  channelData[i] = int16Array[i] / 32768;
332
356
  }
@@ -427,6 +451,7 @@ class Midy {
427
451
  if (queueIndex >= this.timeline.length) {
428
452
  await Promise.all(this.notePromises);
429
453
  this.notePromises = [];
454
+ this.exclusiveClassMap.clear();
430
455
  resolve();
431
456
  return;
432
457
  }
@@ -442,6 +467,7 @@ class Midy {
442
467
  }
443
468
  else if (this.isStopping) {
444
469
  await this.stopNotes(0, true);
470
+ this.exclusiveClassMap.clear();
445
471
  this.notePromises = [];
446
472
  resolve();
447
473
  this.isStopping = false;
@@ -450,6 +476,7 @@ class Midy {
450
476
  }
451
477
  else if (this.isSeeking) {
452
478
  this.stopNotes(0, true);
479
+ this.exclusiveClassMap.clear();
453
480
  this.startTime = this.audioContext.currentTime;
454
481
  queueIndex = this.getQueueIndex(this.resumeTime);
455
482
  offset = this.resumeTime - this.startTime;
@@ -678,14 +705,14 @@ class Midy {
678
705
  return impulse;
679
706
  }
680
707
  createConvolutionReverb(audioContext, impulse) {
681
- const output = new GainNode(audioContext);
708
+ const input = new GainNode(audioContext);
682
709
  const convolverNode = new ConvolverNode(audioContext, {
683
710
  buffer: impulse,
684
711
  });
685
- convolverNode.connect(output);
712
+ input.connect(convolverNode);
686
713
  return {
687
- input: convolverNode,
688
- output,
714
+ input,
715
+ output: convolverNode,
689
716
  convolverNode,
690
717
  };
691
718
  }
@@ -727,7 +754,6 @@ class Midy {
727
754
  // M.R.Schroeder, "Natural Sounding Artificial Reverberation", J.Audio Eng. Soc., vol.10, p.219, 1962
728
755
  createSchroederReverb(audioContext, combFeedbacks, combDelays, allpassFeedbacks, allpassDelays) {
729
756
  const input = new GainNode(audioContext);
730
- const output = new GainNode(audioContext);
731
757
  const mergerGain = new GainNode(audioContext);
732
758
  for (let i = 0; i < combDelays.length; i++) {
733
759
  const comb = this.createCombFilter(audioContext, input, combDelays[i], combFeedbacks[i]);
@@ -738,7 +764,7 @@ class Midy {
738
764
  const allpass = this.createAllpassFilter(audioContext, (i === 0) ? mergerGain : allpasses.at(-1), allpassDelays[i], allpassFeedbacks[i]);
739
765
  allpasses.push(allpass);
740
766
  }
741
- allpasses.at(-1).connect(output);
767
+ const output = allpasses.at(-1);
742
768
  return { input, output };
743
769
  }
744
770
  createChorusEffect(audioContext) {
@@ -969,6 +995,20 @@ class Midy {
969
995
  }
970
996
  note.bufferSource.connect(note.filterNode);
971
997
  note.filterNode.connect(note.volumeNode);
998
+ if (0 < channel.reverbSendLevel && 0 < instrumentKey.reverbEffectsSend) {
999
+ note.reverbEffectsSend = new GainNode(this.audioContext, {
1000
+ gain: instrumentKey.reverbEffectsSend,
1001
+ });
1002
+ note.volumeNode.connect(note.reverbEffectsSend);
1003
+ note.reverbEffectsSend.connect(this.reverbEffect.input);
1004
+ }
1005
+ if (0 < channel.chorusSendLevel && 0 < instrumentKey.chorusEffectsSend) {
1006
+ note.chorusEffectsSend = new GainNode(this.audioContext, {
1007
+ gain: instrumentKey.chorusEffectsSend,
1008
+ });
1009
+ note.volumeNode.connect(note.chorusEffectsSend);
1010
+ note.chorusEffectsSend.connect(this.chorusEffect.input);
1011
+ }
972
1012
  note.bufferSource.start(startTime);
973
1013
  return note;
974
1014
  }
@@ -998,6 +1038,19 @@ class Midy {
998
1038
  if (channel.sostenutoPedal) {
999
1039
  channel.sostenutoNotes.set(noteNumber, note);
1000
1040
  }
1041
+ const exclusiveClass = instrumentKey.exclusiveClass;
1042
+ if (exclusiveClass !== 0) {
1043
+ if (this.exclusiveClassMap.has(exclusiveClass)) {
1044
+ const prevEntry = this.exclusiveClassMap.get(exclusiveClass);
1045
+ const [prevNote, prevChannelNumber] = prevEntry;
1046
+ if (!prevNote.ending) {
1047
+ this.scheduleNoteRelease(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
1048
+ startTime, undefined, // portamentoNoteNumber
1049
+ true);
1050
+ }
1051
+ }
1052
+ this.exclusiveClassMap.set(exclusiveClass, [note, channelNumber]);
1053
+ }
1001
1054
  const scheduledNotes = channel.scheduledNotes;
1002
1055
  if (scheduledNotes.has(noteNumber)) {
1003
1056
  scheduledNotes.get(noteNumber).push(note);
@@ -1010,15 +1063,15 @@ class Midy {
1010
1063
  const now = this.audioContext.currentTime;
1011
1064
  return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now, portamento);
1012
1065
  }
1013
- stopNote(stopTime, endTime, scheduledNotes, index) {
1066
+ stopNote(endTime, stopTime, scheduledNotes, index) {
1014
1067
  const note = scheduledNotes[index];
1015
1068
  note.volumeNode.gain
1016
- .cancelScheduledValues(stopTime)
1017
- .linearRampToValueAtTime(0, endTime);
1069
+ .cancelScheduledValues(endTime)
1070
+ .linearRampToValueAtTime(0, stopTime);
1018
1071
  note.ending = true;
1019
1072
  this.scheduleTask(() => {
1020
1073
  note.bufferSource.loop = false;
1021
- }, endTime);
1074
+ }, stopTime);
1022
1075
  return new Promise((resolve) => {
1023
1076
  note.bufferSource.onended = () => {
1024
1077
  scheduledNotes[index] = null;
@@ -1034,12 +1087,18 @@ class Midy {
1034
1087
  note.vibratoDepth.disconnect();
1035
1088
  note.vibratoLFO.stop();
1036
1089
  }
1090
+ if (note.reverbEffectsSend) {
1091
+ note.reverbEffectsSend.disconnect();
1092
+ }
1093
+ if (note.chorusEffectsSend) {
1094
+ note.chorusEffectsSend.disconnect();
1095
+ }
1037
1096
  resolve();
1038
1097
  };
1039
- note.bufferSource.stop(endTime);
1098
+ note.bufferSource.stop(stopTime);
1040
1099
  });
1041
1100
  }
1042
- scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, portamentoNoteNumber, force) {
1101
+ scheduleNoteRelease(channelNumber, noteNumber, _velocity, endTime, portamentoNoteNumber, force) {
1043
1102
  const channel = this.channels[channelNumber];
1044
1103
  if (!force) {
1045
1104
  if (channel.sustainPedal)
@@ -1057,22 +1116,23 @@ class Midy {
1057
1116
  if (note.ending)
1058
1117
  continue;
1059
1118
  if (portamentoNoteNumber === undefined) {
1060
- const volEndTime = stopTime +
1119
+ const volRelease = endTime +
1061
1120
  note.instrumentKey.volRelease * channel.releaseTime;
1062
- const modRelease = stopTime + note.instrumentKey.modRelease;
1121
+ const modRelease = endTime + note.instrumentKey.modRelease;
1063
1122
  note.filterNode.frequency
1064
- .cancelScheduledValues(stopTime)
1123
+ .cancelScheduledValues(endTime)
1065
1124
  .linearRampToValueAtTime(0, modRelease);
1066
- return this.stopNote(stopTime, volEndTime, scheduledNotes, i);
1125
+ const stopTime = Math.min(volRelease, modRelease);
1126
+ return this.stopNote(endTime, stopTime, scheduledNotes, i);
1067
1127
  }
1068
1128
  else {
1069
- const portamentoTime = stopTime + channel.portamentoTime;
1129
+ const portamentoTime = endTime + channel.portamentoTime;
1070
1130
  const detuneChange = (portamentoNoteNumber - noteNumber) * 100;
1071
1131
  const detune = note.bufferSource.detune.value + detuneChange;
1072
1132
  note.bufferSource.detune
1073
- .cancelScheduledValues(stopTime)
1133
+ .cancelScheduledValues(endTime)
1074
1134
  .linearRampToValueAtTime(detune, portamentoTime);
1075
- return this.stopNote(stopTime, portamentoTime, scheduledNotes, i);
1135
+ return this.stopNote(endTime, portamentoTime, scheduledNotes, i);
1076
1136
  }
1077
1137
  }
1078
1138
  }
@@ -1119,7 +1179,7 @@ class Midy {
1119
1179
  case 0x90:
1120
1180
  return this.noteOn(channelNumber, data1, data2);
1121
1181
  case 0xA0:
1122
- return; // this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
1182
+ return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
1123
1183
  case 0xB0:
1124
1184
  return this.handleControlChange(channelNumber, data1, data2);
1125
1185
  case 0xC0:
@@ -1314,20 +1374,44 @@ class Midy {
1314
1374
  if (0 < reverbSendLevel) {
1315
1375
  const now = this.audioContext.currentTime;
1316
1376
  channel.reverbSendLevel = reverbSendLevel / 127;
1317
- reverbEffect.output.gain.cancelScheduledValues(now);
1318
- reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
1377
+ reverbEffect.input.gain.cancelScheduledValues(now);
1378
+ reverbEffect.input.gain.setValueAtTime(channel.reverbSendLevel, now);
1319
1379
  }
1320
1380
  else {
1321
- channel.merger.disconnect(reverbEffect.input);
1381
+ channel.scheduledNotes.forEach((noteList) => {
1382
+ for (let i = 0; i < noteList.length; i++) {
1383
+ const note = noteList[i];
1384
+ if (!note)
1385
+ continue;
1386
+ if (note.instrumentKey.reverbEffectsSend <= 0)
1387
+ continue;
1388
+ note.reverbEffectsSend.disconnect();
1389
+ }
1390
+ });
1322
1391
  }
1323
1392
  }
1324
1393
  else {
1325
1394
  if (0 < reverbSendLevel) {
1326
- channel.merger.connect(reverbEffect.input);
1327
1395
  const now = this.audioContext.currentTime;
1396
+ channel.scheduledNotes.forEach((noteList) => {
1397
+ for (let i = 0; i < noteList.length; i++) {
1398
+ const note = noteList[i];
1399
+ if (!note)
1400
+ continue;
1401
+ if (note.instrumentKey.reverbEffectsSend <= 0)
1402
+ continue;
1403
+ if (!note.reverbEffectsSend) {
1404
+ note.reverbEffectsSend = new GainNode(this.audioContext, {
1405
+ gain: note.instrumentKey.reverbEffectsSend,
1406
+ });
1407
+ note.volumeNode.connect(note.reverbEffectsSend);
1408
+ }
1409
+ note.reverbEffectsSend.connect(reverbEffect.input);
1410
+ }
1411
+ });
1328
1412
  channel.reverbSendLevel = reverbSendLevel / 127;
1329
- reverbEffect.output.gain.cancelScheduledValues(now);
1330
- reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
1413
+ reverbEffect.input.gain.cancelScheduledValues(now);
1414
+ reverbEffect.input.gain.setValueAtTime(channel.reverbSendLevel, now);
1331
1415
  }
1332
1416
  }
1333
1417
  }
@@ -1338,20 +1422,44 @@ class Midy {
1338
1422
  if (0 < chorusSendLevel) {
1339
1423
  const now = this.audioContext.currentTime;
1340
1424
  channel.chorusSendLevel = chorusSendLevel / 127;
1341
- chorusEffect.output.gain.cancelScheduledValues(now);
1342
- chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
1425
+ chorusEffect.input.gain.cancelScheduledValues(now);
1426
+ chorusEffect.input.gain.setValueAtTime(channel.chorusSendLevel, now);
1343
1427
  }
1344
1428
  else {
1345
- channel.merger.disconnect(chorusEffect.input);
1429
+ channel.scheduledNotes.forEach((noteList) => {
1430
+ for (let i = 0; i < noteList.length; i++) {
1431
+ const note = noteList[i];
1432
+ if (!note)
1433
+ continue;
1434
+ if (note.instrumentKey.chorusEffectsSend <= 0)
1435
+ continue;
1436
+ note.chorusEffectsSend.disconnect();
1437
+ }
1438
+ });
1346
1439
  }
1347
1440
  }
1348
1441
  else {
1349
1442
  if (0 < chorusSendLevel) {
1350
- channel.merger.connect(chorusEffect.input);
1351
1443
  const now = this.audioContext.currentTime;
1444
+ channel.scheduledNotes.forEach((noteList) => {
1445
+ for (let i = 0; i < noteList.length; i++) {
1446
+ const note = noteList[i];
1447
+ if (!note)
1448
+ continue;
1449
+ if (note.instrumentKey.chorusEffectsSend <= 0)
1450
+ continue;
1451
+ if (!note.chorusEffectsSend) {
1452
+ note.chorusEffectsSend = new GainNode(this.audioContext, {
1453
+ gain: note.instrumentKey.chorusEffectsSend,
1454
+ });
1455
+ note.volumeNode.connect(note.chorusEffectsSend);
1456
+ }
1457
+ note.chorusEffectsSend.connect(chorusEffect.input);
1458
+ }
1459
+ });
1352
1460
  channel.chorusSendLevel = chorusSendLevel / 127;
1353
- chorusEffect.output.gain.cancelScheduledValues(now);
1354
- chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
1461
+ chorusEffect.input.gain.cancelScheduledValues(now);
1462
+ chorusEffect.input.gain.setValueAtTime(channel.chorusSendLevel, now);
1355
1463
  }
1356
1464
  }
1357
1465
  }
@@ -1784,10 +1892,8 @@ class Midy {
1784
1892
  }
1785
1893
  setReverbTime(value) {
1786
1894
  this.reverb.time = this.getReverbTime(value);
1787
- const { audioContext, channels, options } = this;
1788
- for (let i = 0; i < channels.length; i++) {
1789
- channels[i].reverbEffect = options.reverbAlgorithm(audioContext);
1790
- }
1895
+ const { audioContext, options } = this;
1896
+ this.reverbEffect = options.reverbAlgorithm(audioContext);
1791
1897
  }
1792
1898
  getReverbTime(value) {
1793
1899
  return Math.pow(Math.E, (value - 40) * 0.025);
@@ -1864,10 +1970,7 @@ class Midy {
1864
1970
  const now = this.audioContext.currentTime;
1865
1971
  const modRate = this.getChorusModRate(value);
1866
1972
  this.chorus.modRate = modRate;
1867
- for (let i = 0; i < this.channels.length; i++) {
1868
- const lfo = this.channels[i].chorusEffect.lfo;
1869
- lfo.frequency.setValueAtTime(modRate, now);
1870
- }
1973
+ this.chorusEffect.lfo.frequency.setValueAtTime(modRate, now);
1871
1974
  }
1872
1975
  getChorusModRate(value) {
1873
1976
  return value * 0.122; // Hz
@@ -1876,12 +1979,9 @@ class Midy {
1876
1979
  const now = this.audioContext.currentTime;
1877
1980
  const modDepth = this.getChorusModDepth(value);
1878
1981
  this.chorus.modDepth = modDepth;
1879
- for (let i = 0; i < this.channels.length; i++) {
1880
- const chorusEffect = this.channels[i].chorusEffect;
1881
- chorusEffect.lfoGain.gain
1882
- .cancelScheduledValues(now)
1883
- .setValueAtTime(modDepth / 2, now);
1884
- }
1982
+ this.chorusEffect.lfoGain.gain
1983
+ .cancelScheduledValues(now)
1984
+ .setValueAtTime(modDepth / 2, now);
1885
1985
  }
1886
1986
  getChorusModDepth(value) {
1887
1987
  return (value + 1) / 3200; // second
@@ -1890,14 +1990,11 @@ class Midy {
1890
1990
  const now = this.audioContext.currentTime;
1891
1991
  const feedback = this.getChorusFeedback(value);
1892
1992
  this.chorus.feedback = feedback;
1893
- for (let i = 0; i < this.channels.length; i++) {
1894
- const chorusEffect = this.channels[i].chorusEffect;
1895
- for (let j = 0; j < chorusEffect.feedbackGains.length; j++) {
1896
- const feedbackGain = chorusEffect.feedbackGains[j];
1897
- feedbackGain.gain
1898
- .cancelScheduledValues(now)
1899
- .setValueAtTime(feedback, now);
1900
- }
1993
+ const chorusEffect = this.chorusEffect;
1994
+ for (let i = 0; i < chorusEffect.feedbackGains.length; i++) {
1995
+ chorusEffect.feedbackGains[i].gain
1996
+ .cancelScheduledValues(now)
1997
+ .setValueAtTime(feedback, now);
1901
1998
  }
1902
1999
  }
1903
2000
  getChorusFeedback(value) {
@@ -1905,15 +2002,28 @@ class Midy {
1905
2002
  }
1906
2003
  setChorusSendToReverb(value) {
1907
2004
  const sendToReverb = this.getChorusSendToReverb(value);
1908
- if (0 < sendToReverb) {
1909
- const now = this.audioContext.currentTime;
2005
+ const sendGain = this.chorusEffect.sendGain;
2006
+ if (0 < this.chorus.sendToReverb) {
1910
2007
  this.chorus.sendToReverb = sendToReverb;
1911
- this.chorusEffect.sendGain.gain
1912
- .cancelScheduledValues(now)
1913
- .setValueAtTime(sendToReverb, now);
2008
+ if (0 < sendToReverb) {
2009
+ const now = this.audioContext.currentTime;
2010
+ sendGain.gain
2011
+ .cancelScheduledValues(now)
2012
+ .setValueAtTime(sendToReverb, now);
2013
+ }
2014
+ else {
2015
+ sendGain.disconnect();
2016
+ }
1914
2017
  }
1915
- else if (this.chorus.sendToReverb !== 0) {
1916
- this.chorusEffect.sendGain.disconnect(this.reverbEffect.input);
2018
+ else {
2019
+ this.chorus.sendToReverb = sendToReverb;
2020
+ if (0 < sendToReverb) {
2021
+ const now = this.audioContext.currentTime;
2022
+ sendGain.connect(this.reverbEffect.input);
2023
+ sendGain.gain
2024
+ .cancelScheduledValues(now)
2025
+ .setValueAtTime(sendToReverb, now);
2026
+ }
1917
2027
  }
1918
2028
  }
1919
2029
  getChorusSendToReverb(value) {
@@ -1,149 +0,0 @@
1
- declare const _default: null;
2
- export default _default;
3
- declare const M: string[];
4
- declare class B {
5
- constructor(e: any);
6
- parsed: any;
7
- getGenerators(e: any, t: any, n: any, r: any): any[];
8
- getPresetGenerators(e: any): any[];
9
- getInstrumentGenerators(e: any): any[];
10
- findInstrumentZone(e: any, t: any, n: any): {} | undefined;
11
- findInstrument(e: any, t: any, n: any): any;
12
- getInstrument(e: any, t: any): any;
13
- getInstrumentKey(e: any, t: any, n: any, r: any): {
14
- start: any;
15
- end: any;
16
- loopStart: any;
17
- loopEnd: any;
18
- modLfoToPitch: any;
19
- vibLfoToPitch: any;
20
- modEnvToPitch: any;
21
- initialFilterFc: any;
22
- initialFilterQ: any;
23
- modLfoToFilterFc: any;
24
- modEnvToFilterFc: any;
25
- modLfoToVolume: any;
26
- chorusEffectsSend: number;
27
- reverbEffectsSend: number;
28
- pan: any;
29
- delayModLFO: number;
30
- freqModLFO: any;
31
- delayVibLFO: number;
32
- freqVibLFO: any;
33
- modDelay: number;
34
- modAttack: number;
35
- modHold: number;
36
- modDecay: number;
37
- modSustain: number;
38
- modRelease: number;
39
- volDelay: number;
40
- volAttack: number;
41
- volHold: number;
42
- volDecay: number;
43
- volSustain: number;
44
- volRelease: number;
45
- initialAttenuation: any;
46
- playbackRate: (e: any) => number;
47
- sample: any;
48
- sampleRate: any;
49
- sampleName: any;
50
- sampleModes: any;
51
- exclusiveClass: any;
52
- } | null;
53
- getPresetNames(): {};
54
- }
55
- declare function S(e: any): {};
56
- declare function V(e: any): {};
57
- declare namespace W {
58
- let startAddrsOffset: m;
59
- let endAddrsOffset: m;
60
- let startloopAddrsOffset: m;
61
- let endloopAddrsOffset: m;
62
- let startAddrsCoarseOffset: m;
63
- let modLfoToPitch: m;
64
- let vibLfoToPitch: m;
65
- let modEnvToPitch: m;
66
- let initialFilterFc: m;
67
- let initialFilterQ: m;
68
- let modLfoToFilterFc: m;
69
- let modEnvToFilterFc: m;
70
- let endAddrsCoarseOffset: m;
71
- let modLfoToVolume: m;
72
- let chorusEffectsSend: m;
73
- let reverbEffectsSend: m;
74
- let pan: m;
75
- let delayModLFO: m;
76
- let freqModLFO: m;
77
- let delayVibLFO: m;
78
- let freqVibLFO: m;
79
- let delayModEnv: m;
80
- let attackModEnv: m;
81
- let holdModEnv: m;
82
- let decayModEnv: m;
83
- let sustainModEnv: m;
84
- let releaseModEnv: m;
85
- let keynumToModEnvHold: m;
86
- let keynumToModEnvDecay: m;
87
- let delayVolEnv: m;
88
- let attackVolEnv: m;
89
- let holdVolEnv: m;
90
- let decayVolEnv: m;
91
- let sustainVolEnv: m;
92
- let releaseVolEnv: m;
93
- let keynumToVolEnvHold: m;
94
- let keynumToVolEnvDecay: m;
95
- let instrument: m;
96
- let keyRange: d;
97
- let velRange: d;
98
- let startloopAddrsCoarseOffset: m;
99
- let keynum: m;
100
- let velocity: m;
101
- let initialAttenuation: m;
102
- let endloopAddrsCoarseOffset: m;
103
- let coarseTune: m;
104
- let fineTune: m;
105
- let sampleID: m;
106
- let sampleModes: m;
107
- let scaleTuning: m;
108
- let exclusiveClass: m;
109
- let overridingRootKey: m;
110
- }
111
- declare function L(e: any): boolean;
112
- declare function p(e: any, r?: {}): {
113
- samples: any;
114
- presetHeaders: any[];
115
- presetZone: any[];
116
- presetModulators: any[];
117
- presetGenerators: any[];
118
- instruments: any[];
119
- instrumentZone: any[];
120
- instrumentModulators: any[];
121
- instrumentGenerators: any[];
122
- sampleHeaders: any[];
123
- info: s;
124
- samplingData: {
125
- offsetMSB: any;
126
- offsetLSB: any;
127
- };
128
- };
129
- declare function H(e: any): number;
130
- declare class m {
131
- constructor(e: any, t: any, n: any);
132
- min: any;
133
- value: any;
134
- max: any;
135
- clamp(): number;
136
- }
137
- declare class d {
138
- static parse(e: any): d;
139
- constructor(e: any, t: any);
140
- lo: any;
141
- hi: any;
142
- in(e: any): boolean;
143
- }
144
- declare class s {
145
- static parse(t: any, n: any): s;
146
- constructor(e: any, t: any, n: any, r: any, a: any, o: any, s: any, i: any, l: any, d: any, u: any);
147
- }
148
- export { M as RangeGeneratorNames, B as SoundFont, S as createInstrumentGeneratorObject, V as createPresetGeneratorObject, W as defaultInstrumentZone, L as isRangeGenerator, p as parse, H as timecentToSecond };
149
- //# sourceMappingURL=+esm.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"+esm.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js"],"names":[],"mappings":";;AAM0lV,0BAAyB;AAAugF;IAAQ,oBAA2H;IAAd,YAAa;IAAC,qDAAoJ;IAAA,mCAAoP;IAAA,uCAAwQ;IAAA,2DAAiP;IAAA,4CAAmX;IAAA,mCAAuL;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAA49D;IAAA,qBAAqK;CAAC;AAApoL,+BAA2R;AAAzd,+BAA8L;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAjO,oCAAmC;AAA7yE;;;;;;;;;;;;;;;;EAA27B;AAAorO,mCAAwC;AAAziR;IAAQ,oCAAyU;IAAnC,SAAU;IAAC,WAAY;IAAC,SAAU;IAAC,gBAAgE;CAAC;AAA19G;IAAqQ,wBAAsE;IAAnU,4BAAyN;IAApB,QAAS;IAAC,QAAS;IAAC,oBAAoC;CAAuE;AAAv5F;IAAshC,gCAAqa;IAAn7C,oGAA8gC;CAAsa"}