@marmooo/midy 0.1.5 → 0.1.6

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.
@@ -252,12 +252,14 @@ class MidyGM2 {
252
252
  addSoundFont(soundFont) {
253
253
  const index = this.soundFonts.length;
254
254
  this.soundFonts.push(soundFont);
255
- soundFont.parsed.presetHeaders.forEach((presetHeader) => {
255
+ const presetHeaders = soundFont.parsed.presetHeaders;
256
+ for (let i = 0; i < presetHeaders.length; i++) {
257
+ const presetHeader = presetHeaders[i];
256
258
  if (!presetHeader.presetName.startsWith("\u0000")) { // TODO: Only SF3 generated by PolyPone?
257
259
  const banks = this.soundFontTable[presetHeader.preset];
258
260
  banks.set(presetHeader.bank, index);
259
261
  }
260
- });
262
+ }
261
263
  }
262
264
  async loadSoundFont(soundFontUrl) {
263
265
  const response = await fetch(soundFontUrl);
@@ -306,27 +308,25 @@ class MidyGM2 {
306
308
  return channels;
307
309
  }
308
310
  async createNoteBuffer(instrumentKey, isSF3) {
311
+ const sampleStart = instrumentKey.start;
309
312
  const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
310
313
  if (isSF3) {
311
- const sample = new Uint8Array(instrumentKey.sample.length);
312
- sample.set(instrumentKey.sample);
314
+ const sample = instrumentKey.sample.slice(sampleStart, sampleEnd);
313
315
  const audioBuffer = await this.audioContext.decodeAudioData(sample.buffer);
314
- for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
315
- const channelData = audioBuffer.getChannelData(channel);
316
- channelData.set(channelData.subarray(0, sampleEnd));
317
- }
318
316
  return audioBuffer;
319
317
  }
320
318
  else {
321
- const sample = instrumentKey.sample.subarray(0, sampleEnd);
322
- const floatSample = this.convertToFloat32Array(sample);
319
+ const sample = instrumentKey.sample.subarray(sampleStart, sampleEnd);
323
320
  const audioBuffer = new AudioBuffer({
324
321
  numberOfChannels: 1,
325
322
  length: sample.length,
326
323
  sampleRate: instrumentKey.sampleRate,
327
324
  });
328
325
  const channelData = audioBuffer.getChannelData(0);
329
- channelData.set(floatSample);
326
+ const int16Array = new Int16Array(sample.buffer);
327
+ for (let i = 0; i < int16Array.length; i++) {
328
+ channelData[i] = int16Array[i] / 32768;
329
+ }
330
330
  return audioBuffer;
331
331
  }
332
332
  }
@@ -342,13 +342,23 @@ class MidyGM2 {
342
342
  }
343
343
  return bufferSource;
344
344
  }
345
- convertToFloat32Array(uint8Array) {
346
- const int16Array = new Int16Array(uint8Array.buffer);
347
- const float32Array = new Float32Array(int16Array.length);
348
- for (let i = 0; i < int16Array.length; i++) {
349
- float32Array[i] = int16Array[i] / 32768;
345
+ findPortamentoTarget(queueIndex) {
346
+ const endEvent = this.timeline[queueIndex];
347
+ if (!this.channels[endEvent.channel].portamento)
348
+ return;
349
+ const endTime = endEvent.startTime;
350
+ let target;
351
+ while (++queueIndex < this.timeline.length) {
352
+ const event = this.timeline[queueIndex];
353
+ if (endTime !== event.startTime)
354
+ break;
355
+ if (event.type !== "noteOn")
356
+ continue;
357
+ if (!target || event.noteNumber < target.noteNumber) {
358
+ target = event;
359
+ }
350
360
  }
351
- return float32Array;
361
+ return target;
352
362
  }
353
363
  async scheduleTimelineEvents(t, offset, queueIndex) {
354
364
  while (queueIndex < this.timeline.length) {
@@ -358,12 +368,15 @@ class MidyGM2 {
358
368
  switch (event.type) {
359
369
  case "noteOn":
360
370
  if (event.velocity !== 0) {
361
- await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
371
+ await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset, event.portamento);
362
372
  break;
363
373
  }
364
374
  /* falls through */
365
375
  case "noteOff": {
366
- const notePromise = this.scheduleNoteRelease(this.omni ? 0 : event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
376
+ const portamentoTarget = this.findPortamentoTarget(queueIndex);
377
+ if (portamentoTarget)
378
+ portamentoTarget.portamento = true;
379
+ const notePromise = this.scheduleNoteRelease(this.omni ? 0 : event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset, portamentoTarget?.noteNumber, false);
367
380
  if (notePromise) {
368
381
  this.notePromises.push(notePromise);
369
382
  }
@@ -464,9 +477,11 @@ class MidyGM2 {
464
477
  bankLSB: this.channels[i].bankLSB,
465
478
  };
466
479
  }
467
- midi.tracks.forEach((track) => {
480
+ for (let i = 0; i < midi.tracks.length; i++) {
481
+ const track = midi.tracks[i];
468
482
  let currentTicks = 0;
469
- track.forEach((event) => {
483
+ for (let j = 0; j < track.length; j++) {
484
+ const event = track[j];
470
485
  currentTicks += event.deltaTime;
471
486
  event.ticks = currentTicks;
472
487
  switch (event.type) {
@@ -519,16 +534,18 @@ class MidyGM2 {
519
534
  }
520
535
  delete event.deltaTime;
521
536
  timeline.push(event);
522
- });
523
- });
537
+ }
538
+ }
524
539
  const priority = {
525
540
  controller: 0,
526
541
  sysEx: 1,
542
+ noteOff: 2, // for portamento
543
+ noteOn: 3,
527
544
  };
528
545
  timeline.sort((a, b) => {
529
546
  if (a.ticks !== b.ticks)
530
547
  return a.ticks - b.ticks;
531
- return (priority[a.type] || 2) - (priority[b.type] || 2);
548
+ return (priority[a.type] || 4) - (priority[b.type] || 4);
532
549
  });
533
550
  let prevTempoTime = 0;
534
551
  let prevTempoTicks = 0;
@@ -545,7 +562,7 @@ class MidyGM2 {
545
562
  }
546
563
  return { instruments, timeline };
547
564
  }
548
- async stopChannelNotes(channelNumber, velocity, stopPedal) {
565
+ async stopChannelNotes(channelNumber, velocity, force) {
549
566
  const now = this.audioContext.currentTime;
550
567
  const channel = this.channels[channelNumber];
551
568
  channel.scheduledNotes.forEach((noteList) => {
@@ -553,16 +570,17 @@ class MidyGM2 {
553
570
  const note = noteList[i];
554
571
  if (!note)
555
572
  continue;
556
- const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
573
+ const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, undefined, // portamentoNoteNumber
574
+ force);
557
575
  this.notePromises.push(promise);
558
576
  }
559
577
  });
560
578
  channel.scheduledNotes.clear();
561
579
  await Promise.all(this.notePromises);
562
580
  }
563
- stopNotes(velocity, stopPedal) {
581
+ stopNotes(velocity, force) {
564
582
  for (let i = 0; i < this.channels.length; i++) {
565
- this.stopChannelNotes(i, velocity, stopPedal);
583
+ this.stopChannelNotes(i, velocity, force);
566
584
  }
567
585
  return Promise.all(this.notePromises);
568
586
  }
@@ -776,6 +794,17 @@ class MidyGM2 {
776
794
  return instrumentKey.playbackRate(noteNumber) *
777
795
  Math.pow(2, semitoneOffset / 12);
778
796
  }
797
+ setPortamentoStartVolumeEnvelope(channel, note) {
798
+ const { instrumentKey, startTime } = note;
799
+ const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
800
+ const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
801
+ const volDelay = startTime + instrumentKey.volDelay;
802
+ const portamentoTime = volDelay + channel.portamentoTime;
803
+ note.volumeNode.gain
804
+ .cancelScheduledValues(startTime)
805
+ .setValueAtTime(0, volDelay)
806
+ .linearRampToValueAtTime(sustainVolume, portamentoTime);
807
+ }
779
808
  setVolumeEnvelope(note) {
780
809
  const { instrumentKey, startTime } = note;
781
810
  const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
@@ -815,6 +844,25 @@ class MidyGM2 {
815
844
  const maxFrequency = 20000; // max Hz of initialFilterFc
816
845
  return Math.max(minFrequency, Math.min(frequency, maxFrequency));
817
846
  }
847
+ setPortamentoStartFilterEnvelope(channel, note) {
848
+ const { instrumentKey, noteNumber, startTime } = note;
849
+ const softPedalFactor = 1 -
850
+ (0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
851
+ const baseFreq = this.centToHz(instrumentKey.initialFilterFc) *
852
+ softPedalFactor;
853
+ const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
854
+ const sustainFreq = baseFreq +
855
+ (peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
856
+ const adjustedBaseFreq = this.clampCutoffFrequency(baseFreq);
857
+ const adjustedSustainFreq = this.clampCutoffFrequency(sustainFreq);
858
+ const portamentoTime = startTime + channel.portamentoTime;
859
+ const modDelay = startTime + instrumentKey.modDelay;
860
+ note.filterNode.frequency
861
+ .cancelScheduledValues(startTime)
862
+ .setValueAtTime(adjustedBaseFreq, startTime)
863
+ .setValueAtTime(adjustedBaseFreq, modDelay)
864
+ .linearRampToValueAtTime(adjustedSustainFreq, portamentoTime);
865
+ }
818
866
  setFilterEnvelope(channel, note) {
819
867
  const { instrumentKey, noteNumber, startTime } = note;
820
868
  const softPedalFactor = 1 -
@@ -882,17 +930,23 @@ class MidyGM2 {
882
930
  note.vibratoLFO.connect(note.vibratoDepth);
883
931
  note.vibratoDepth.connect(note.bufferSource.detune);
884
932
  }
885
- async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
933
+ async createNote(channel, instrumentKey, noteNumber, velocity, startTime, portamento, isSF3) {
886
934
  const semitoneOffset = this.calcSemitoneOffset(channel);
887
935
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
888
936
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
889
937
  note.volumeNode = new GainNode(this.audioContext);
890
938
  note.filterNode = new BiquadFilterNode(this.audioContext, {
891
939
  type: "lowpass",
892
- Q: instrumentKey.initialFilterQ / 10 * channel.filterResonance, // dB
940
+ Q: instrumentKey.initialFilterQ / 10, // dB
893
941
  });
894
- this.setVolumeEnvelope(note);
895
- this.setFilterEnvelope(channel, note);
942
+ if (portamento) {
943
+ this.setPortamentoStartVolumeEnvelope(channel, note);
944
+ this.setPortamentoStartFilterEnvelope(channel, note);
945
+ }
946
+ else {
947
+ this.setVolumeEnvelope(note);
948
+ this.setFilterEnvelope(channel, note);
949
+ }
896
950
  if (0 < channel.vibratoDepth) {
897
951
  this.startVibrato(channel, note, startTime);
898
952
  }
@@ -909,7 +963,7 @@ class MidyGM2 {
909
963
  }
910
964
  note.bufferSource.connect(note.filterNode);
911
965
  note.filterNode.connect(note.volumeNode);
912
- note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
966
+ note.bufferSource.start(startTime);
913
967
  return note;
914
968
  }
915
969
  calcBank(channel, channelNumber) {
@@ -921,7 +975,7 @@ class MidyGM2 {
921
975
  }
922
976
  return channel.bank;
923
977
  }
924
- async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
978
+ async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime, portamento) {
925
979
  const channel = this.channels[channelNumber];
926
980
  const bankNumber = this.calcBank(channel, channelNumber);
927
981
  const soundFontIndex = this.soundFontTable[channel.program].get(bankNumber);
@@ -932,7 +986,7 @@ class MidyGM2 {
932
986
  const instrumentKey = soundFont.getInstrumentKey(bankNumber, channel.program, noteNumber, velocity);
933
987
  if (!instrumentKey)
934
988
  return;
935
- const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
989
+ const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, portamento, isSF3);
936
990
  note.volumeNode.connect(channel.gainL);
937
991
  note.volumeNode.connect(channel.gainR);
938
992
  if (channel.sostenutoPedal) {
@@ -946,13 +1000,42 @@ class MidyGM2 {
946
1000
  scheduledNotes.set(noteNumber, [note]);
947
1001
  }
948
1002
  }
949
- noteOn(channelNumber, noteNumber, velocity) {
1003
+ noteOn(channelNumber, noteNumber, velocity, portamento) {
950
1004
  const now = this.audioContext.currentTime;
951
- return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
1005
+ return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now, portamento);
1006
+ }
1007
+ stopNote(stopTime, endTime, scheduledNotes, index) {
1008
+ const note = scheduledNotes[index];
1009
+ note.volumeNode.gain
1010
+ .cancelScheduledValues(stopTime)
1011
+ .linearRampToValueAtTime(0, endTime);
1012
+ note.ending = true;
1013
+ this.scheduleTask(() => {
1014
+ note.bufferSource.loop = false;
1015
+ }, endTime);
1016
+ return new Promise((resolve) => {
1017
+ note.bufferSource.onended = () => {
1018
+ scheduledNotes[index] = null;
1019
+ note.bufferSource.disconnect();
1020
+ note.volumeNode.disconnect();
1021
+ note.filterNode.disconnect();
1022
+ if (note.modulationDepth) {
1023
+ note.volumeDepth.disconnect();
1024
+ note.modulationDepth.disconnect();
1025
+ note.modulationLFO.stop();
1026
+ }
1027
+ if (note.vibratoDepth) {
1028
+ note.vibratoDepth.disconnect();
1029
+ note.vibratoLFO.stop();
1030
+ }
1031
+ resolve();
1032
+ };
1033
+ note.bufferSource.stop(endTime);
1034
+ });
952
1035
  }
953
- scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, stopPedal = false) {
1036
+ scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, portamentoNoteNumber, force) {
954
1037
  const channel = this.channels[channelNumber];
955
- if (stopPedal) {
1038
+ if (!force) {
956
1039
  if (channel.sustainPedal)
957
1040
  return;
958
1041
  if (channel.sostenutoNotes.has(noteNumber))
@@ -967,38 +1050,28 @@ class MidyGM2 {
967
1050
  continue;
968
1051
  if (note.ending)
969
1052
  continue;
970
- const volEndTime = stopTime + note.instrumentKey.volRelease;
971
- note.volumeNode.gain
972
- .cancelScheduledValues(stopTime)
973
- .linearRampToValueAtTime(0, volEndTime);
974
- const modRelease = stopTime + note.instrumentKey.modRelease;
975
- note.filterNode.frequency
976
- .cancelScheduledValues(stopTime)
977
- .linearRampToValueAtTime(0, modRelease);
978
- note.ending = true;
979
- this.scheduleTask(() => {
980
- note.bufferSource.loop = false;
981
- }, stopTime);
982
- return new Promise((resolve) => {
983
- note.bufferSource.onended = () => {
984
- scheduledNotes[i] = null;
985
- note.bufferSource.disconnect();
986
- note.volumeNode.disconnect();
987
- note.filterNode.disconnect();
988
- if (note.modulationDepth) {
989
- note.volumeDepth.disconnect();
990
- note.modulationDepth.disconnect();
991
- note.modulationLFO.stop();
992
- }
993
- resolve();
994
- };
995
- note.bufferSource.stop(volEndTime);
996
- });
1053
+ if (portamentoNoteNumber === undefined) {
1054
+ const volEndTime = stopTime + note.instrumentKey.volRelease;
1055
+ const modRelease = stopTime + note.instrumentKey.modRelease;
1056
+ note.filterNode.frequency
1057
+ .cancelScheduledValues(stopTime)
1058
+ .linearRampToValueAtTime(0, modRelease);
1059
+ return this.stopNote(stopTime, volEndTime, scheduledNotes, i);
1060
+ }
1061
+ else {
1062
+ const portamentoTime = stopTime + channel.portamentoTime;
1063
+ const detuneChange = (portamentoNoteNumber - noteNumber) * 100;
1064
+ const detune = note.bufferSource.detune.value + detuneChange;
1065
+ note.bufferSource.detune
1066
+ .cancelScheduledValues(stopTime)
1067
+ .linearRampToValueAtTime(detune, portamentoTime);
1068
+ return this.stopNote(stopTime, portamentoTime, scheduledNotes, i);
1069
+ }
997
1070
  }
998
1071
  }
999
- releaseNote(channelNumber, noteNumber, velocity) {
1072
+ releaseNote(channelNumber, noteNumber, velocity, portamentoNoteNumber) {
1000
1073
  const now = this.audioContext.currentTime;
1001
- return this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now);
1074
+ return this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, portamentoNoteNumber, false);
1002
1075
  }
1003
1076
  releaseSustainPedal(channelNumber, halfVelocity) {
1004
1077
  const velocity = halfVelocity * 2;
@@ -1146,12 +1219,14 @@ class MidyGM2 {
1146
1219
  this.updateModulation(channel);
1147
1220
  }
1148
1221
  setPortamentoTime(channelNumber, portamentoTime) {
1149
- this.channels[channelNumber].portamentoTime = portamentoTime / 127;
1222
+ const channel = this.channels[channelNumber];
1223
+ const factor = 5 * Math.log(10) / 127;
1224
+ channel.portamentoTime = Math.exp(factor * portamentoTime);
1150
1225
  }
1151
1226
  setVolume(channelNumber, volume) {
1152
1227
  const channel = this.channels[channelNumber];
1153
1228
  channel.volume = volume / 127;
1154
- this.updateChannelGain(channel);
1229
+ this.updateChannelVolume(channel);
1155
1230
  }
1156
1231
  panToGain(pan) {
1157
1232
  const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
@@ -1163,12 +1238,12 @@ class MidyGM2 {
1163
1238
  setPan(channelNumber, pan) {
1164
1239
  const channel = this.channels[channelNumber];
1165
1240
  channel.pan = pan;
1166
- this.updateChannelGain(channel);
1241
+ this.updateChannelVolume(channel);
1167
1242
  }
1168
1243
  setExpression(channelNumber, expression) {
1169
1244
  const channel = this.channels[channelNumber];
1170
1245
  channel.expression = expression / 127;
1171
- this.updateChannelGain(channel);
1246
+ this.updateChannelVolume(channel);
1172
1247
  }
1173
1248
  setBankLSB(channelNumber, lsb) {
1174
1249
  this.channels[channelNumber].bankLSB = lsb;
@@ -1177,7 +1252,7 @@ class MidyGM2 {
1177
1252
  this.channels[channelNumber].dataLSB = value;
1178
1253
  this.handleRPN(channelNumber);
1179
1254
  }
1180
- updateChannelGain(channel) {
1255
+ updateChannelVolume(channel) {
1181
1256
  const now = this.audioContext.currentTime;
1182
1257
  const volume = channel.volume * channel.expression;
1183
1258
  const { gainLeft, gainRight } = this.panToGain(channel.pan);
@@ -1195,12 +1270,12 @@ class MidyGM2 {
1195
1270
  this.releaseSustainPedal(channelNumber, value);
1196
1271
  }
1197
1272
  }
1198
- // TODO
1199
1273
  setPortamento(channelNumber, value) {
1200
1274
  this.channels[channelNumber].portamento = value >= 64;
1201
1275
  }
1202
1276
  setReverbSendLevel(channelNumber, reverbSendLevel) {
1203
1277
  const channel = this.channels[channelNumber];
1278
+ const reverbEffect = this.reverbEffect;
1204
1279
  if (0 < channel.reverbSendLevel) {
1205
1280
  if (0 < reverbSendLevel) {
1206
1281
  const now = this.audioContext.currentTime;
@@ -1428,20 +1503,22 @@ class MidyGM2 {
1428
1503
  }
1429
1504
  }
1430
1505
  GM1SystemOn() {
1431
- this.channels.forEach((channel) => {
1506
+ for (let i = 0; i < this.channels.length; i++) {
1507
+ const channel = this.channels[i];
1432
1508
  channel.bankMSB = 0;
1433
1509
  channel.bankLSB = 0;
1434
1510
  channel.bank = 0;
1435
- });
1511
+ }
1436
1512
  this.channels[9].bankMSB = 1;
1437
1513
  this.channels[9].bank = 128;
1438
1514
  }
1439
1515
  GM2SystemOn() {
1440
- this.channels.forEach((channel) => {
1516
+ for (let i = 0; i < this.channels.length; i++) {
1517
+ const channel = this.channels[i];
1441
1518
  channel.bankMSB = 121;
1442
1519
  channel.bankLSB = 0;
1443
1520
  channel.bank = 121 * 128;
1444
- });
1521
+ }
1445
1522
  this.channels[9].bankMSB = 120;
1446
1523
  this.channels[9].bank = 120 * 128;
1447
1524
  }
@@ -1751,7 +1828,7 @@ Object.defineProperty(MidyGM2, "channelSettings", {
1751
1828
  currentBufferSource: null,
1752
1829
  volume: 100 / 127,
1753
1830
  pan: 64,
1754
- portamentoTime: 0,
1831
+ portamentoTime: 1, // sec
1755
1832
  reverbSendLevel: 0,
1756
1833
  chorusSendLevel: 0,
1757
1834
  vibratoRate: 1,
@@ -64,7 +64,6 @@ export class MidyGMLite {
64
64
  createChannels(audioContext: any): any[];
65
65
  createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
66
66
  createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
67
- convertToFloat32Array(uint8Array: any): Float32Array;
68
67
  scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
69
68
  getQueueIndex(second: any): number;
70
69
  playNotes(): Promise<any>;
@@ -74,8 +73,8 @@ export class MidyGMLite {
74
73
  instruments: Set<any>;
75
74
  timeline: any[];
76
75
  };
77
- stopChannelNotes(channelNumber: any, velocity: any, stopPedal: any): Promise<void>;
78
- stopNotes(velocity: any, stopPedal: any): Promise<any[]>;
76
+ stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
77
+ stopNotes(velocity: any, force: any): Promise<any[]>;
79
78
  start(): Promise<void>;
80
79
  stop(): void;
81
80
  pause(): void;
@@ -97,10 +96,11 @@ export class MidyGMLite {
97
96
  createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
98
97
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
99
98
  noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
100
- scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
101
- releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
99
+ stopNote(stopTime: any, endTime: any, scheduledNotes: any, index: any): Promise<any>;
100
+ scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, force: any): void;
101
+ releaseNote(channelNumber: any, noteNumber: any, velocity: any): void;
102
102
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
103
- handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
103
+ handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<void>;
104
104
  handleProgramChange(channelNumber: any, program: any): void;
105
105
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
106
106
  setPitchBend(channelNumber: any, pitchBend: any): void;
@@ -129,7 +129,7 @@ export class MidyGMLite {
129
129
  setPan(channelNumber: any, pan: any): void;
130
130
  setExpression(channelNumber: any, expression: any): void;
131
131
  dataEntryLSB(channelNumber: any, value: any): void;
132
- updateChannelGain(channel: any): void;
132
+ updateChannelVolume(channel: any): void;
133
133
  setSustainPedal(channelNumber: any, value: any): void;
134
134
  handleRPN(channelNumber: any): void;
135
135
  setRPNMSB(channelNumber: any, value: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAOC;IA7CD,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;IAuBhB,kBAAgC;IAChC,gBAA4C;IAC5C;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA8DC;IAED,mFAmBC;IAED,yDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,4BAEC;IAED,yCAEC;IAED,mFAGC;IAED,mCAeC;IAED,+CAwBC;IAED,6CAIC;IAED,mCAsBC;IAED,+DA0BC;IAED,wHAmCC;IAED,kGA8BC;IAED,0EAGC;IAED,uIA2CC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED;;;;;;;;;;;;;MAeC;IAED,2EASC;IAED,qCAkBC;IAED,8DAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAaC;IAED,kDAKC;IAED,iEAOC;IAED,+CAEC;IAED,8CAEC;IAED,+CAEC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAj/BD;IAQE,gFAKC;IAZD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
1
+ {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAOC;IA7CD,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;IAuBhB,kBAAgC;IAChC,gBAA4C;IAC5C;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,+DAuBC;IAED,mEAWC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;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,4BAEC;IAED,yCAEC;IAED,mFAGC;IAED,mCAeC;IAED,+CAwBC;IAED,6CAIC;IAED,mCAsBC;IAED,+DA0BC;IAED,wHAgCC;IAED,kGA8BC;IAED,0EAGC;IAED,qFA4BC;IAED,0GAsBC;IAED,sEAGC;IAED,kEAeC;IAED,iFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED;;;;;;;;;;;;;MAeC;IAED,2EASC;IAED,qCAkBC;IAED,8DAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,wCAUC;IAED,sDAMC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAaC;IAED,kDAKC;IAED,iEAOC;IAED,+CAEC;IAED,8CAEC;IAED,+CAEC;IAED,4DAgBC;IAED,oBASC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAj/BD;IAQE,gFAKC;IAZD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}