@marmooo/midy 0.4.6 → 0.4.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.
@@ -25,6 +25,7 @@ export class MidyGMLite extends EventTarget {
25
25
  voiceCounter: Map<any, any>;
26
26
  voiceCache: Map<any, any>;
27
27
  realtimeVoiceCache: Map<any, any>;
28
+ decodeMethod: string;
28
29
  isPlaying: boolean;
29
30
  isPausing: boolean;
30
31
  isPaused: boolean;
@@ -71,6 +72,7 @@ export class MidyGMLite extends EventTarget {
71
72
  merger: any;
72
73
  };
73
74
  createChannels(audioContext: any): any[];
75
+ decodeOggVorbis(sample: any): Promise<any>;
74
76
  createAudioBuffer(voiceParams: any): Promise<any>;
75
77
  createBufferSource(channel: any, voiceParams: any, audioBuffer: any): any;
76
78
  scheduleTimelineEvents(scheduleTime: any, queueIndex: any): any;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAqHA;IAuCE;;;;;;;;;MASE;IAEF,+BAgBC;IA7DD,gCAAgC;IAChC,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iCAEG;IACH,cAAU;IACV,cAAa;IACb,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAeA,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IAMnD,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAeC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDASC;IAED,0EAUC;IAED,gEAsDC;IAED,mCASC;IAED,uBAUC;IAED,yDAqCC;IAED,2BA0EC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAQC;IAED,uBAMC;IAED,sBAIC;IAED,uBAMC;IAED,wBAIC;IAED,0BAKC;IAED,8BAMC;IAED,wBAYC;IAED,sBAIC;IAED,kEAWC;IAED,kFAYC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,wCAIC;IAED,2DAIC;IAED,6CAEC;IAED,sDAeC;IAED,4DASC;IAED,qDAkBC;IAED,6CAIC;IAED,sDA6BC;IAED,kEAqBC;IAED,4GAkCC;IAED,uEA6CC;IAED,0EAiBC;IAED,8EAiBC;IAED,oEAUC;IAED,0FAwBC;IAED,gCASC;IAED,iEAwBC;IAED,4FAsBC;IAED,6CAUC;IAED,qDAUC;IAED,qFAeC;IAED,+BAmBC;IAED,kDAOC;IAED,sFA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAYC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;;MAoCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDAUC;IAED,4EAKC;IAED,mEAKC;IAED;;;MAMC;IAED,gEAKC;IAED,uEAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,uDAcC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCAUC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
1
+ {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAiIA;IAwCE;;;;;;;;;MASE;IAEF,+BAgBC;IA9DD,gCAAgC;IAChC,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,qBAAqC;IACrC,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iCAEG;IACH,cAAU;IACV,cAAa;IACb,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAeA,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IAMnD,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBA6BC;IAED,8DAeC;IAED;;;;MAeC;IAED,yCAaC;IAED,2CAsBC;IAED,kDA6BC;IAED,0EAUC;IAED,gEAsDC;IAED,mCASC;IAED,uBAUC;IAED,yDAqCC;IAED,2BA0EC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAQC;IAED,uBAMC;IAED,sBAIC;IAED,uBAMC;IAED,wBAIC;IAED,0BAKC;IAED,8BAMC;IAED,wBAYC;IAED,sBAIC;IAED,kEAWC;IAED,kFAYC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,wCAIC;IAED,2DAIC;IAED,6CAEC;IAED,sDAeC;IAED,4DASC;IAED,qDAkBC;IAED,6CAIC;IAED,sDA6BC;IAED,kEAqBC;IAED,4GAkCC;IAED,uEA6CC;IAED,0EAiBC;IAED,8EAiBC;IAED,oEAUC;IAED,0FAwBC;IAED,gCASC;IAED,iEAwBC;IAED,4FAsBC;IAED,6CAUC;IAED,qDAUC;IAED,qFAeC;IAED,+BAmBC;IAED,kDAOC;IAED,sFA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAYC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;;MAoCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAYC;IAED,wDAUC;IAED,4EAKC;IAED,mEAKC;IAED;;;MAMC;IAED,gEAKC;IAED,uEAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,uDAcC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCAUC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
@@ -1,5 +1,15 @@
1
1
  import { parseMidi } from "midi-file";
2
2
  import { parse, SoundFont } from "@marmooo/soundfont-parser";
3
+ import { OggVorbisDecoderWebWorker } from "@wasm-audio-decoders/ogg-vorbis";
4
+ let decoderPromise = null;
5
+ let decoderQueue = Promise.resolve();
6
+ function initDecoder() {
7
+ if (!decoderPromise) {
8
+ const instance = new OggVorbisDecoderWebWorker();
9
+ decoderPromise = instance.ready.then(() => instance);
10
+ }
11
+ return decoderPromise;
12
+ }
3
13
  class Note {
4
14
  constructor(noteNumber, velocity, startTime) {
5
15
  Object.defineProperty(this, "voice", {
@@ -38,37 +48,37 @@ class Note {
38
48
  writable: true,
39
49
  value: void 0
40
50
  });
41
- Object.defineProperty(this, "filterNode", {
51
+ Object.defineProperty(this, "filterEnvelopeNode", {
42
52
  enumerable: true,
43
53
  configurable: true,
44
54
  writable: true,
45
55
  value: void 0
46
56
  });
47
- Object.defineProperty(this, "filterDepth", {
57
+ Object.defineProperty(this, "volumeEnvelopeNode", {
48
58
  enumerable: true,
49
59
  configurable: true,
50
60
  writable: true,
51
61
  value: void 0
52
62
  });
53
- Object.defineProperty(this, "volumeEnvelopeNode", {
63
+ Object.defineProperty(this, "modLfo", {
54
64
  enumerable: true,
55
65
  configurable: true,
56
66
  writable: true,
57
67
  value: void 0
58
- });
59
- Object.defineProperty(this, "volumeDepth", {
68
+ }); // CC#1 modulation LFO
69
+ Object.defineProperty(this, "modLfoToPitch", {
60
70
  enumerable: true,
61
71
  configurable: true,
62
72
  writable: true,
63
73
  value: void 0
64
74
  });
65
- Object.defineProperty(this, "modulationLFO", {
75
+ Object.defineProperty(this, "modLfoToFilterFc", {
66
76
  enumerable: true,
67
77
  configurable: true,
68
78
  writable: true,
69
79
  value: void 0
70
80
  });
71
- Object.defineProperty(this, "modulationDepth", {
81
+ Object.defineProperty(this, "modLfoToVolume", {
72
82
  enumerable: true,
73
83
  configurable: true,
74
84
  writable: true,
@@ -268,6 +278,12 @@ export class MidyGMLite extends EventTarget {
268
278
  writable: true,
269
279
  value: new Map()
270
280
  });
281
+ Object.defineProperty(this, "decodeMethod", {
282
+ enumerable: true,
283
+ configurable: true,
284
+ writable: true,
285
+ value: "wasm-audio-decoders"
286
+ });
271
287
  Object.defineProperty(this, "isPlaying", {
272
288
  enumerable: true,
273
289
  configurable: true,
@@ -435,14 +451,6 @@ export class MidyGMLite extends EventTarget {
435
451
  voiceCounter.set(audioBufferId, (voiceCounter.get(audioBufferId) ?? 0) + 1);
436
452
  break;
437
453
  }
438
- case "controller":
439
- if (event.controllerType === 0) {
440
- this.setBankMSB(event.channel, event.value);
441
- }
442
- else if (event.controllerType === 32) {
443
- this.setBankLSB(event.channel, event.value);
444
- }
445
- break;
446
454
  case "programChange":
447
455
  this.setProgramChange(event.channel, event.programNumber, event.startTime);
448
456
  }
@@ -500,11 +508,57 @@ export class MidyGMLite extends EventTarget {
500
508
  });
501
509
  return channels;
502
510
  }
511
+ decodeOggVorbis(sample) {
512
+ const task = decoderQueue.then(async () => {
513
+ const decoder = await initDecoder();
514
+ const slice = sample.data.slice();
515
+ const { channelData, sampleRate, errors } = await decoder.decodeFile(slice);
516
+ if (0 < errors.length) {
517
+ throw new Error(errors.join(", "));
518
+ }
519
+ const audioBuffer = new AudioBuffer({
520
+ numberOfChannels: channelData.length,
521
+ length: channelData[0].length,
522
+ sampleRate,
523
+ });
524
+ for (let ch = 0; ch < channelData.length; ch++) {
525
+ audioBuffer.getChannelData(ch).set(channelData[ch]);
526
+ }
527
+ return audioBuffer;
528
+ });
529
+ decoderQueue = task.catch(() => { });
530
+ return task;
531
+ }
503
532
  async createAudioBuffer(voiceParams) {
504
- const { sample, start, end } = voiceParams;
505
- const sampleEnd = sample.data.length + end;
506
- const audioBuffer = await sample.toAudioBuffer(this.audioContext, start, sampleEnd);
507
- return audioBuffer;
533
+ const sample = voiceParams.sample;
534
+ if (sample.type === "compressed") {
535
+ switch (this.decodeMethod) {
536
+ case "decodeAudioData": {
537
+ // https://jakearchibald.com/2016/sounds-fun/
538
+ // https://github.com/WebAudio/web-audio-api/issues/1091
539
+ // decodeAudioData() has priming issues on Safari
540
+ const arrayBuffer = sample.data.slice().buffer;
541
+ return await this.audioContext.decodeAudioData(arrayBuffer);
542
+ }
543
+ case "wasm-audio-decoders":
544
+ return await this.decodeOggVorbis(sample);
545
+ default:
546
+ throw new Error(`Unknown decodeMethod: ${this.decodeMethod}`);
547
+ }
548
+ }
549
+ else {
550
+ const data = sample.data;
551
+ const end = data.length + voiceParams.end;
552
+ const subarray = data.subarray(voiceParams.start, end);
553
+ const pcm = sample.decodePCM(subarray);
554
+ const audioBuffer = new AudioBuffer({
555
+ numberOfChannels: 1,
556
+ length: pcm.length,
557
+ sampleRate: sample.sampleHeader.sampleRate,
558
+ });
559
+ audioBuffer.getChannelData(0).set(pcm);
560
+ return audioBuffer;
561
+ }
508
562
  }
509
563
  createBufferSource(channel, voiceParams, audioBuffer) {
510
564
  const bufferSource = new AudioBufferSourceNode(this.audioContext);
@@ -572,7 +626,7 @@ export class MidyGMLite extends EventTarget {
572
626
  const channels = this.channels;
573
627
  for (let ch = 0; ch < channels.length; ch++) {
574
628
  channels[ch].scheduledNotes = [];
575
- this.resetChannelStates(i);
629
+ this.resetChannelStates(ch);
576
630
  }
577
631
  }
578
632
  updateStates(queueIndex, nextQueueIndex) {
@@ -953,7 +1007,7 @@ export class MidyGMLite extends EventTarget {
953
1007
  const modHold = modAttack + voiceParams.modHold;
954
1008
  const decayDuration = voiceParams.modDecay;
955
1009
  note.adjustedBaseFreq = adjustedBaseFreq;
956
- note.filterNode.frequency
1010
+ note.filterEnvelopeNode.frequency
957
1011
  .cancelScheduledValues(scheduleTime)
958
1012
  .setValueAtTime(adjustedBaseFreq, startTime)
959
1013
  .setValueAtTime(adjustedBaseFreq, modDelay)
@@ -964,23 +1018,23 @@ export class MidyGMLite extends EventTarget {
964
1018
  startModulation(channel, note, scheduleTime) {
965
1019
  const audioContext = this.audioContext;
966
1020
  const { voiceParams } = note;
967
- note.modulationLFO = new OscillatorNode(audioContext, {
1021
+ note.modLfo = new OscillatorNode(audioContext, {
968
1022
  frequency: this.centToHz(voiceParams.freqModLFO),
969
1023
  });
970
- note.filterDepth = new GainNode(audioContext, {
1024
+ note.modLfoToFilterFc = new GainNode(audioContext, {
971
1025
  gain: voiceParams.modLfoToFilterFc,
972
1026
  });
973
- note.modulationDepth = new GainNode(audioContext);
1027
+ note.modLfoToPitch = new GainNode(audioContext);
974
1028
  this.setModLfoToPitch(channel, note, scheduleTime);
975
- note.volumeDepth = new GainNode(audioContext);
1029
+ note.modLfoToVolume = new GainNode(audioContext);
976
1030
  this.setModLfoToVolume(note, scheduleTime);
977
- note.modulationLFO.start(note.startTime + voiceParams.delayModLFO);
978
- note.modulationLFO.connect(note.filterDepth);
979
- note.filterDepth.connect(note.filterNode.frequency);
980
- note.modulationLFO.connect(note.modulationDepth);
981
- note.modulationDepth.connect(note.bufferSource.detune);
982
- note.modulationLFO.connect(note.volumeDepth);
983
- note.volumeDepth.connect(note.volumeEnvelopeNode.gain);
1031
+ note.modLfo.start(note.startTime + voiceParams.delayModLFO);
1032
+ note.modLfo.connect(note.modLfoToFilterFc);
1033
+ note.modLfoToFilterFc.connect(note.filterEnvelopeNode.frequency);
1034
+ note.modLfo.connect(note.modLfoToPitch);
1035
+ note.modLfoToPitch.connect(note.bufferSource.detune);
1036
+ note.modLfo.connect(note.modLfoToVolume);
1037
+ note.modLfoToVolume.connect(note.volumeEnvelopeNode.gain);
984
1038
  }
985
1039
  async getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime) {
986
1040
  const audioBufferId = this.getVoiceId(channel, noteNumber, velocity);
@@ -1021,7 +1075,7 @@ export class MidyGMLite extends EventTarget {
1021
1075
  const audioBuffer = await this.getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime);
1022
1076
  note.bufferSource = this.createBufferSource(channel, voiceParams, audioBuffer);
1023
1077
  note.volumeEnvelopeNode = new GainNode(audioContext);
1024
- note.filterNode = new BiquadFilterNode(audioContext, {
1078
+ note.filterEnvelopeNode = new BiquadFilterNode(audioContext, {
1025
1079
  type: "lowpass",
1026
1080
  Q: voiceParams.initialFilterQ / 10, // dB
1027
1081
  });
@@ -1032,8 +1086,8 @@ export class MidyGMLite extends EventTarget {
1032
1086
  if (0 < state.modulationDepthMSB) {
1033
1087
  this.startModulation(channel, note, now);
1034
1088
  }
1035
- note.bufferSource.connect(note.filterNode);
1036
- note.filterNode.connect(note.volumeEnvelopeNode);
1089
+ note.bufferSource.connect(note.filterEnvelopeNode);
1090
+ note.filterEnvelopeNode.connect(note.volumeEnvelopeNode);
1037
1091
  if (voiceParams.sample.type === "compressed") {
1038
1092
  const offset = voiceParams.start / audioBuffer.sampleRate;
1039
1093
  note.bufferSource.start(startTime, offset);
@@ -1115,19 +1169,19 @@ export class MidyGMLite extends EventTarget {
1115
1169
  }
1116
1170
  disconnectNote(note) {
1117
1171
  note.bufferSource.disconnect();
1118
- note.filterNode.disconnect();
1172
+ note.filterEnvelopeNode.disconnect();
1119
1173
  note.volumeEnvelopeNode.disconnect();
1120
- if (note.modulationDepth) {
1121
- note.volumeDepth.disconnect();
1122
- note.modulationDepth.disconnect();
1123
- note.modulationLFO.stop();
1174
+ if (note.modLfoToPitch) {
1175
+ note.modLfoToVolume.disconnect();
1176
+ note.modLfoToPitch.disconnect();
1177
+ note.modLfo.stop();
1124
1178
  }
1125
1179
  }
1126
1180
  releaseNote(channel, note, endTime) {
1127
1181
  endTime ??= this.audioContext.currentTime;
1128
1182
  const volDuration = note.voiceParams.volRelease;
1129
1183
  const volRelease = endTime + volDuration;
1130
- note.filterNode.frequency
1184
+ note.filterEnvelopeNode.frequency
1131
1185
  .cancelScheduledValues(endTime)
1132
1186
  .setTargetAtTime(note.adjustedBaseFreq, endTime, note.voiceParams.modRelease * releaseCurve);
1133
1187
  note.volumeEnvelopeNode.gain
@@ -1259,12 +1313,12 @@ export class MidyGMLite extends EventTarget {
1259
1313
  this.applyVoiceParams(channel, 14, scheduleTime);
1260
1314
  }
1261
1315
  setModLfoToPitch(channel, note, scheduleTime) {
1262
- if (note.modulationDepth) {
1316
+ if (note.modLfoToPitch) {
1263
1317
  const modLfoToPitch = note.voiceParams.modLfoToPitch;
1264
1318
  const baseDepth = Math.abs(modLfoToPitch) +
1265
1319
  channel.state.modulationDepthMSB;
1266
1320
  const depth = baseDepth * Math.sign(modLfoToPitch);
1267
- note.modulationDepth.gain
1321
+ note.modLfoToPitch.gain
1268
1322
  .cancelScheduledValues(scheduleTime)
1269
1323
  .setValueAtTime(depth, scheduleTime);
1270
1324
  }
@@ -1274,29 +1328,29 @@ export class MidyGMLite extends EventTarget {
1274
1328
  }
1275
1329
  setModLfoToFilterFc(note, scheduleTime) {
1276
1330
  const modLfoToFilterFc = note.voiceParams.modLfoToFilterFc;
1277
- note.filterDepth.gain
1331
+ note.modLfoToFilterFc.gain
1278
1332
  .cancelScheduledValues(scheduleTime)
1279
1333
  .setValueAtTime(modLfoToFilterFc, scheduleTime);
1280
1334
  }
1281
1335
  setModLfoToVolume(note, scheduleTime) {
1282
1336
  const modLfoToVolume = note.voiceParams.modLfoToVolume;
1283
1337
  const baseDepth = cbToRatio(Math.abs(modLfoToVolume)) - 1;
1284
- const volumeDepth = baseDepth * Math.sign(modLfoToVolume);
1285
- note.volumeDepth.gain
1338
+ const depth = baseDepth * Math.sign(modLfoToVolume);
1339
+ note.modLfoToVolume.gain
1286
1340
  .cancelScheduledValues(scheduleTime)
1287
- .setValueAtTime(volumeDepth, scheduleTime);
1341
+ .setValueAtTime(depth, scheduleTime);
1288
1342
  }
1289
1343
  setDelayModLFO(note, scheduleTime) {
1290
1344
  const startTime = note.startTime;
1291
1345
  if (startTime < scheduleTime)
1292
1346
  return;
1293
- note.modulationLFO.stop(scheduleTime);
1294
- note.modulationLFO.start(startTime + note.voiceParams.delayModLFO);
1295
- note.modulationLFO.connect(note.filterDepth);
1347
+ note.modLfo.stop(scheduleTime);
1348
+ note.modLfo.start(startTime + note.voiceParams.delayModLFO);
1349
+ note.modLfo.connect(note.modLfoToFilterFc);
1296
1350
  }
1297
1351
  setFreqModLFO(note, scheduleTime) {
1298
1352
  const freqModLFO = note.voiceParams.freqModLFO;
1299
- note.modulationLFO.frequency
1353
+ note.modLfo.frequency
1300
1354
  .cancelScheduledValues(scheduleTime)
1301
1355
  .setValueAtTime(freqModLFO, scheduleTime);
1302
1356
  }
@@ -1393,6 +1447,8 @@ export class MidyGMLite extends EventTarget {
1393
1447
  return handlers;
1394
1448
  }
1395
1449
  setControlChange(channelNumber, controllerType, value, scheduleTime) {
1450
+ if (!(0 <= scheduleTime))
1451
+ scheduleTime = this.audioContext.currentTime;
1396
1452
  const handler = this.controlChangeHandlers[controllerType];
1397
1453
  if (handler) {
1398
1454
  handler.call(this, channelNumber, value, scheduleTime);
@@ -1407,8 +1463,8 @@ export class MidyGMLite extends EventTarget {
1407
1463
  const depth = channel.state.modulationDepthMSB *
1408
1464
  channel.modulationDepthRange;
1409
1465
  this.processScheduledNotes(channel, (note) => {
1410
- if (note.modulationDepth) {
1411
- note.modulationDepth.gain.setValueAtTime(depth, scheduleTime);
1466
+ if (note.modLfoToPitch) {
1467
+ note.modLfoToPitch.gain.setValueAtTime(depth, scheduleTime);
1412
1468
  }
1413
1469
  else {
1414
1470
  this.startModulation(channel, note, scheduleTime);
package/esm/midy.d.ts CHANGED
@@ -49,6 +49,7 @@ export class Midy extends EventTarget {
49
49
  voiceCounter: Map<any, any>;
50
50
  voiceCache: Map<any, any>;
51
51
  realtimeVoiceCache: Map<any, any>;
52
+ decodeMethod: string;
52
53
  isPlaying: boolean;
53
54
  isPausing: boolean;
54
55
  isPaused: boolean;
@@ -71,6 +72,9 @@ export class Midy extends EventTarget {
71
72
  channelToNotes: Map<any, any>;
72
73
  noteToChannel: Map<any, any>;
73
74
  };
75
+ decoder: OggVorbisDecoderWebWorker;
76
+ decoderReady: Promise<void>;
77
+ decoderQueue: Promise<void>;
74
78
  audioContext: any;
75
79
  masterVolume: any;
76
80
  scheduler: any;
@@ -91,6 +95,7 @@ export class Midy extends EventTarget {
91
95
  };
92
96
  controlChangeHandlers: any[];
93
97
  keyBasedControllerHandlers: any[];
98
+ effectHandlers: any[];
94
99
  channels: any[];
95
100
  reverbEffect: {
96
101
  input: any;
@@ -118,6 +123,7 @@ export class Midy extends EventTarget {
118
123
  };
119
124
  resetChannelTable(channel: any): void;
120
125
  createChannels(audioContext: any): any[];
126
+ decodeOggVorbis(sample: any): Promise<any>;
121
127
  createAudioBuffer(voiceParams: any): Promise<any>;
122
128
  isLoopDrum(channel: any, noteNumber: any): boolean;
123
129
  createBufferSource(channel: any, noteNumber: any, voiceParams: any, audioBuffer: any): any;
@@ -184,6 +190,7 @@ export class Midy extends EventTarget {
184
190
  getPitchIncrementSpeed(value: any): number;
185
191
  setPortamentoVolumeEnvelope(channel: any, note: any, scheduleTime: any): void;
186
192
  setVolumeEnvelope(channel: any, note: any, scheduleTime: any): void;
193
+ setVolumeNode(channel: any, note: any, scheduleTime: any): void;
187
194
  setPortamentoDetune(channel: any, note: any, scheduleTime: any): void;
188
195
  setDetune(channel: any, note: any, scheduleTime: any): void;
189
196
  setPortamentoPitchEnvelope(channel: any, note: any, scheduleTime: any): void;
@@ -270,7 +277,6 @@ export class Midy extends EventTarget {
270
277
  getSoftPedalFactor(channel: any, note: any): number;
271
278
  setSoftPedal(channelNumber: any, softPedal: any, scheduleTime: any): void;
272
279
  setFilterResonance(channelNumber: any, ccValue: any, scheduleTime: any): void;
273
- getRelativeKeyBasedValue(channel: any, note: any, controllerType: any): any;
274
280
  setReleaseTime(channelNumber: any, releaseTime: any, scheduleTime: any): void;
275
281
  setAttackTime(channelNumber: any, attackTime: any, scheduleTime: any): void;
276
282
  setBrightness(channelNumber: any, brightness: any, scheduleTime: any): void;
@@ -340,23 +346,34 @@ export class Midy extends EventTarget {
340
346
  getChannelBitmap(data: any): any[];
341
347
  handleScaleOctaveTuning1ByteFormatSysEx(data: any, realtime: any, scheduleTime: any): void;
342
348
  handleScaleOctaveTuning2ByteFormatSysEx(data: any, realtime: any, scheduleTime: any): void;
349
+ calcEffectValue(channel: any, note: any, destination: any): number;
350
+ calcChannelEffectValue(channel: any, destination: any): number;
351
+ calcControlChangeEffectValue(channel: any, destination: any): number;
352
+ calcChannelPressureEffectValue(channel: any, destination: any): number;
353
+ calcNoteEffectValue(channel: any, note: any, destination: any): number;
354
+ getChannelPitchControl(channel: any): number;
355
+ getNotePitchControl(channel: any, note: any): number;
343
356
  getPitchControl(channel: any, note: any): number;
344
357
  getFilterCutoffControl(channel: any, note: any): number;
358
+ getChannelAmplitudeControl(channel: any): number;
359
+ getNoteAmplitudeControl(channel: any, note: any): number;
345
360
  getAmplitudeControl(channel: any, note: any): number;
346
361
  getLFOPitchDepth(channel: any, note: any): number;
347
362
  getLFOFilterDepth(channel: any, note: any): number;
348
363
  getLFOAmplitudeDepth(channel: any, note: any): number;
349
- setEffects(channel: any, note: any, table: any, scheduleTime: any): void;
364
+ createEffectHandlers(): any[];
365
+ setControlChangeEffects(channel: any, note: any, scheduleTime: any): void;
366
+ setPressureEffects(channel: any, note: any, tableName: any, scheduleTime: any): void;
350
367
  handlePressureSysEx(data: any, tableName: any, scheduleTime: any): void;
351
- initControlTable(): Int8Array<ArrayBuffer>;
352
- setControlChangeEffects(channel: any, controllerType: any, scheduleTime: any): void;
353
368
  handleControlChangeSysEx(data: any, scheduleTime: any): void;
369
+ getRelativeKeyBasedValue(channel: any, keyNumber: any, controllerType: any): any;
354
370
  getKeyBasedValue(channel: any, keyNumber: any, controllerType: any): any;
355
371
  createKeyBasedControllerHandlers(): any[];
356
372
  handleKeyBasedInstrumentControlSysEx(data: any, scheduleTime: any): void;
357
373
  handleSysEx(data: any, scheduleTime: any): void;
358
374
  scheduleTask(callback: any, scheduleTime: any): Promise<any>;
359
375
  }
376
+ import { OggVorbisDecoderWebWorker } from "@wasm-audio-decoders/ogg-vorbis";
360
377
  declare class Note {
361
378
  constructor(noteNumber: any, velocity: any, startTime: any);
362
379
  voice: any;
@@ -365,14 +382,15 @@ declare class Note {
365
382
  index: number;
366
383
  ending: boolean;
367
384
  bufferSource: any;
368
- filterNode: any;
369
- filterDepth: any;
385
+ filterEnvelopeNode: any;
370
386
  volumeEnvelopeNode: any;
371
- volumeDepth: any;
372
- modulationLFO: any;
373
- modulationDepth: any;
374
- vibratoLFO: any;
375
- vibratoDepth: any;
387
+ volumeNode: any;
388
+ modLfo: any;
389
+ modLfoToPitch: any;
390
+ modLfoToFilterFc: any;
391
+ modLfoToVolume: any;
392
+ vibLfo: any;
393
+ vibLfoToPitch: any;
376
394
  reverbSend: any;
377
395
  chorusSend: any;
378
396
  portamentoNoteNumber: number;
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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"}