@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.
package/esm/midy.js CHANGED
@@ -249,12 +249,14 @@ export class Midy {
249
249
  addSoundFont(soundFont) {
250
250
  const index = this.soundFonts.length;
251
251
  this.soundFonts.push(soundFont);
252
- soundFont.parsed.presetHeaders.forEach((presetHeader) => {
252
+ const presetHeaders = soundFont.parsed.presetHeaders;
253
+ for (let i = 0; i < presetHeaders.length; i++) {
254
+ const presetHeader = presetHeaders[i];
253
255
  if (!presetHeader.presetName.startsWith("\u0000")) { // TODO: Only SF3 generated by PolyPone?
254
256
  const banks = this.soundFontTable[presetHeader.preset];
255
257
  banks.set(presetHeader.bank, index);
256
258
  }
257
- });
259
+ }
258
260
  }
259
261
  async loadSoundFont(soundFontUrl) {
260
262
  const response = await fetch(soundFontUrl);
@@ -306,27 +308,25 @@ export class Midy {
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 @@ export class Midy {
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 @@ export class Midy {
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
  }
@@ -467,9 +480,11 @@ export class Midy {
467
480
  bankLSB: this.channels[i].bankLSB,
468
481
  };
469
482
  }
470
- midi.tracks.forEach((track) => {
483
+ for (let i = 0; i < midi.tracks.length; i++) {
484
+ const track = midi.tracks[i];
471
485
  let currentTicks = 0;
472
- track.forEach((event) => {
486
+ for (let j = 0; j < track.length; j++) {
487
+ const event = track[j];
473
488
  currentTicks += event.deltaTime;
474
489
  event.ticks = currentTicks;
475
490
  switch (event.type) {
@@ -522,16 +537,18 @@ export class Midy {
522
537
  }
523
538
  delete event.deltaTime;
524
539
  timeline.push(event);
525
- });
526
- });
540
+ }
541
+ }
527
542
  const priority = {
528
543
  controller: 0,
529
544
  sysEx: 1,
545
+ noteOff: 2, // for portamento
546
+ noteOn: 3,
530
547
  };
531
548
  timeline.sort((a, b) => {
532
549
  if (a.ticks !== b.ticks)
533
550
  return a.ticks - b.ticks;
534
- return (priority[a.type] || 2) - (priority[b.type] || 2);
551
+ return (priority[a.type] || 4) - (priority[b.type] || 4);
535
552
  });
536
553
  let prevTempoTime = 0;
537
554
  let prevTempoTicks = 0;
@@ -548,7 +565,7 @@ export class Midy {
548
565
  }
549
566
  return { instruments, timeline };
550
567
  }
551
- async stopChannelNotes(channelNumber, velocity, stopPedal) {
568
+ async stopChannelNotes(channelNumber, velocity, force) {
552
569
  const now = this.audioContext.currentTime;
553
570
  const channel = this.channels[channelNumber];
554
571
  channel.scheduledNotes.forEach((noteList) => {
@@ -556,16 +573,17 @@ export class Midy {
556
573
  const note = noteList[i];
557
574
  if (!note)
558
575
  continue;
559
- const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
576
+ const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, undefined, // portamentoNoteNumber
577
+ force);
560
578
  this.notePromises.push(promise);
561
579
  }
562
580
  });
563
581
  channel.scheduledNotes.clear();
564
582
  await Promise.all(this.notePromises);
565
583
  }
566
- stopNotes(velocity, stopPedal) {
584
+ stopNotes(velocity, force) {
567
585
  for (let i = 0; i < this.channels.length; i++) {
568
- this.stopChannelNotes(i, velocity, stopPedal);
586
+ this.stopChannelNotes(i, velocity, force);
569
587
  }
570
588
  return Promise.all(this.notePromises);
571
589
  }
@@ -779,6 +797,17 @@ export class Midy {
779
797
  return instrumentKey.playbackRate(noteNumber) *
780
798
  Math.pow(2, semitoneOffset / 12);
781
799
  }
800
+ setPortamentoStartVolumeEnvelope(channel, note) {
801
+ const { instrumentKey, startTime } = note;
802
+ const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
803
+ const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
804
+ const volDelay = startTime + instrumentKey.volDelay;
805
+ const portamentoTime = volDelay + channel.portamentoTime;
806
+ note.volumeNode.gain
807
+ .cancelScheduledValues(startTime)
808
+ .setValueAtTime(0, volDelay)
809
+ .linearRampToValueAtTime(sustainVolume, portamentoTime);
810
+ }
782
811
  setVolumeEnvelope(channel, note) {
783
812
  const { instrumentKey, startTime } = note;
784
813
  const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
@@ -818,6 +847,25 @@ export class Midy {
818
847
  const maxFrequency = 20000; // max Hz of initialFilterFc
819
848
  return Math.max(minFrequency, Math.min(frequency, maxFrequency));
820
849
  }
850
+ setPortamentoStartFilterEnvelope(channel, note) {
851
+ const { instrumentKey, noteNumber, startTime } = note;
852
+ const softPedalFactor = 1 -
853
+ (0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
854
+ const baseFreq = this.centToHz(instrumentKey.initialFilterFc) *
855
+ softPedalFactor * channel.brightness;
856
+ const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor * channel.brightness;
857
+ const sustainFreq = baseFreq +
858
+ (peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
859
+ const adjustedBaseFreq = this.clampCutoffFrequency(baseFreq);
860
+ const adjustedSustainFreq = this.clampCutoffFrequency(sustainFreq);
861
+ const portamentoTime = startTime + channel.portamentoTime;
862
+ const modDelay = startTime + instrumentKey.modDelay;
863
+ note.filterNode.frequency
864
+ .cancelScheduledValues(startTime)
865
+ .setValueAtTime(adjustedBaseFreq, startTime)
866
+ .setValueAtTime(adjustedBaseFreq, modDelay)
867
+ .linearRampToValueAtTime(adjustedSustainFreq, portamentoTime);
868
+ }
821
869
  setFilterEnvelope(channel, note) {
822
870
  const { instrumentKey, noteNumber, startTime } = note;
823
871
  const softPedalFactor = 1 -
@@ -885,7 +933,7 @@ export class Midy {
885
933
  note.vibratoLFO.connect(note.vibratoDepth);
886
934
  note.vibratoDepth.connect(note.bufferSource.detune);
887
935
  }
888
- async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
936
+ async createNote(channel, instrumentKey, noteNumber, velocity, startTime, portamento, isSF3) {
889
937
  const semitoneOffset = this.calcSemitoneOffset(channel);
890
938
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
891
939
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
@@ -894,8 +942,14 @@ export class Midy {
894
942
  type: "lowpass",
895
943
  Q: instrumentKey.initialFilterQ / 10 * channel.filterResonance, // dB
896
944
  });
897
- this.setVolumeEnvelope(channel, note);
898
- this.setFilterEnvelope(channel, note);
945
+ if (portamento) {
946
+ this.setPortamentoStartVolumeEnvelope(channel, note);
947
+ this.setPortamentoStartFilterEnvelope(channel, note);
948
+ }
949
+ else {
950
+ this.setVolumeEnvelope(channel, note);
951
+ this.setFilterEnvelope(channel, note);
952
+ }
899
953
  if (0 < channel.vibratoDepth) {
900
954
  this.startVibrato(channel, note, startTime);
901
955
  }
@@ -912,7 +966,7 @@ export class Midy {
912
966
  }
913
967
  note.bufferSource.connect(note.filterNode);
914
968
  note.filterNode.connect(note.volumeNode);
915
- note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
969
+ note.bufferSource.start(startTime);
916
970
  return note;
917
971
  }
918
972
  calcBank(channel, channelNumber) {
@@ -924,7 +978,7 @@ export class Midy {
924
978
  }
925
979
  return channel.bank;
926
980
  }
927
- async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
981
+ async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime, portamento) {
928
982
  const channel = this.channels[channelNumber];
929
983
  const bankNumber = this.calcBank(channel, channelNumber);
930
984
  const soundFontIndex = this.soundFontTable[channel.program].get(bankNumber);
@@ -935,7 +989,7 @@ export class Midy {
935
989
  const instrumentKey = soundFont.getInstrumentKey(bankNumber, channel.program, noteNumber, velocity);
936
990
  if (!instrumentKey)
937
991
  return;
938
- const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
992
+ const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, portamento, isSF3);
939
993
  note.volumeNode.connect(channel.gainL);
940
994
  note.volumeNode.connect(channel.gainR);
941
995
  if (channel.sostenutoPedal) {
@@ -949,13 +1003,42 @@ export class Midy {
949
1003
  scheduledNotes.set(noteNumber, [note]);
950
1004
  }
951
1005
  }
952
- noteOn(channelNumber, noteNumber, velocity) {
1006
+ noteOn(channelNumber, noteNumber, velocity, portamento) {
953
1007
  const now = this.audioContext.currentTime;
954
- return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
1008
+ return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now, portamento);
955
1009
  }
956
- scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, stopPedal = false) {
1010
+ stopNote(stopTime, endTime, scheduledNotes, index) {
1011
+ const note = scheduledNotes[index];
1012
+ note.volumeNode.gain
1013
+ .cancelScheduledValues(stopTime)
1014
+ .linearRampToValueAtTime(0, endTime);
1015
+ note.ending = true;
1016
+ this.scheduleTask(() => {
1017
+ note.bufferSource.loop = false;
1018
+ }, endTime);
1019
+ return new Promise((resolve) => {
1020
+ note.bufferSource.onended = () => {
1021
+ scheduledNotes[index] = null;
1022
+ note.bufferSource.disconnect();
1023
+ note.volumeNode.disconnect();
1024
+ note.filterNode.disconnect();
1025
+ if (note.modulationDepth) {
1026
+ note.volumeDepth.disconnect();
1027
+ note.modulationDepth.disconnect();
1028
+ note.modulationLFO.stop();
1029
+ }
1030
+ if (note.vibratoDepth) {
1031
+ note.vibratoDepth.disconnect();
1032
+ note.vibratoLFO.stop();
1033
+ }
1034
+ resolve();
1035
+ };
1036
+ note.bufferSource.stop(endTime);
1037
+ });
1038
+ }
1039
+ scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, portamentoNoteNumber, force) {
957
1040
  const channel = this.channels[channelNumber];
958
- if (stopPedal) {
1041
+ if (!force) {
959
1042
  if (channel.sustainPedal)
960
1043
  return;
961
1044
  if (channel.sostenutoNotes.has(noteNumber))
@@ -970,43 +1053,29 @@ export class Midy {
970
1053
  continue;
971
1054
  if (note.ending)
972
1055
  continue;
973
- const volEndTime = stopTime +
974
- note.instrumentKey.volRelease * channel.releaseTime;
975
- note.volumeNode.gain
976
- .cancelScheduledValues(stopTime)
977
- .linearRampToValueAtTime(0, volEndTime);
978
- const modRelease = stopTime + note.instrumentKey.modRelease;
979
- note.filterNode.frequency
980
- .cancelScheduledValues(stopTime)
981
- .linearRampToValueAtTime(0, modRelease);
982
- note.ending = true;
983
- this.scheduleTask(() => {
984
- note.bufferSource.loop = false;
985
- }, stopTime);
986
- return new Promise((resolve) => {
987
- note.bufferSource.onended = () => {
988
- scheduledNotes[i] = null;
989
- note.bufferSource.disconnect();
990
- note.volumeNode.disconnect();
991
- note.filterNode.disconnect();
992
- if (note.modulationDepth) {
993
- note.volumeDepth.disconnect();
994
- note.modulationDepth.disconnect();
995
- note.modulationLFO.stop();
996
- }
997
- if (note.vibratoDepth) {
998
- note.vibratoDepth.disconnect();
999
- note.vibratoLFO.stop();
1000
- }
1001
- resolve();
1002
- };
1003
- note.bufferSource.stop(volEndTime);
1004
- });
1056
+ if (portamentoNoteNumber === undefined) {
1057
+ const volEndTime = stopTime +
1058
+ note.instrumentKey.volRelease * channel.releaseTime;
1059
+ const modRelease = stopTime + note.instrumentKey.modRelease;
1060
+ note.filterNode.frequency
1061
+ .cancelScheduledValues(stopTime)
1062
+ .linearRampToValueAtTime(0, modRelease);
1063
+ return this.stopNote(stopTime, volEndTime, scheduledNotes, i);
1064
+ }
1065
+ else {
1066
+ const portamentoTime = stopTime + channel.portamentoTime;
1067
+ const detuneChange = (portamentoNoteNumber - noteNumber) * 100;
1068
+ const detune = note.bufferSource.detune.value + detuneChange;
1069
+ note.bufferSource.detune
1070
+ .cancelScheduledValues(stopTime)
1071
+ .linearRampToValueAtTime(detune, portamentoTime);
1072
+ return this.stopNote(stopTime, portamentoTime, scheduledNotes, i);
1073
+ }
1005
1074
  }
1006
1075
  }
1007
- releaseNote(channelNumber, noteNumber, velocity) {
1076
+ releaseNote(channelNumber, noteNumber, velocity, portamentoNoteNumber) {
1008
1077
  const now = this.audioContext.currentTime;
1009
- return this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now);
1078
+ return this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, portamentoNoteNumber, false);
1010
1079
  }
1011
1080
  releaseSustainPedal(channelNumber, halfVelocity) {
1012
1081
  const velocity = halfVelocity * 2;
@@ -1181,12 +1250,14 @@ export class Midy {
1181
1250
  this.updateModulation(channel);
1182
1251
  }
1183
1252
  setPortamentoTime(channelNumber, portamentoTime) {
1184
- this.channels[channelNumber].portamentoTime = portamentoTime / 127;
1253
+ const channel = this.channels[channelNumber];
1254
+ const factor = 5 * Math.log(10) / 127;
1255
+ channel.portamentoTime = Math.exp(factor * portamentoTime);
1185
1256
  }
1186
1257
  setVolume(channelNumber, volume) {
1187
1258
  const channel = this.channels[channelNumber];
1188
1259
  channel.volume = volume / 127;
1189
- this.updateChannelGain(channel);
1260
+ this.updateChannelVolume(channel);
1190
1261
  }
1191
1262
  panToGain(pan) {
1192
1263
  const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
@@ -1198,12 +1269,12 @@ export class Midy {
1198
1269
  setPan(channelNumber, pan) {
1199
1270
  const channel = this.channels[channelNumber];
1200
1271
  channel.pan = pan;
1201
- this.updateChannelGain(channel);
1272
+ this.updateChannelVolume(channel);
1202
1273
  }
1203
1274
  setExpression(channelNumber, expression) {
1204
1275
  const channel = this.channels[channelNumber];
1205
1276
  channel.expression = expression / 127;
1206
- this.updateChannelGain(channel);
1277
+ this.updateChannelVolume(channel);
1207
1278
  }
1208
1279
  setBankLSB(channelNumber, lsb) {
1209
1280
  this.channels[channelNumber].bankLSB = lsb;
@@ -1212,7 +1283,7 @@ export class Midy {
1212
1283
  this.channels[channelNumber].dataLSB = value;
1213
1284
  this.handleRPN(channelNumber, 0);
1214
1285
  }
1215
- updateChannelGain(channel) {
1286
+ updateChannelVolume(channel) {
1216
1287
  const now = this.audioContext.currentTime;
1217
1288
  const volume = channel.volume * channel.expression;
1218
1289
  const { gainLeft, gainRight } = this.panToGain(channel.pan);
@@ -1230,12 +1301,12 @@ export class Midy {
1230
1301
  this.releaseSustainPedal(channelNumber, value);
1231
1302
  }
1232
1303
  }
1233
- // TODO
1234
1304
  setPortamento(channelNumber, value) {
1235
1305
  this.channels[channelNumber].portamento = value >= 64;
1236
1306
  }
1237
1307
  setReverbSendLevel(channelNumber, reverbSendLevel) {
1238
1308
  const channel = this.channels[channelNumber];
1309
+ const reverbEffect = this.reverbEffect;
1239
1310
  if (0 < channel.reverbSendLevel) {
1240
1311
  if (0 < reverbSendLevel) {
1241
1312
  const now = this.audioContext.currentTime;
@@ -1554,20 +1625,22 @@ export class Midy {
1554
1625
  }
1555
1626
  }
1556
1627
  GM1SystemOn() {
1557
- this.channels.forEach((channel) => {
1628
+ for (let i = 0; i < this.channels.length; i++) {
1629
+ const channel = this.channels[i];
1558
1630
  channel.bankMSB = 0;
1559
1631
  channel.bankLSB = 0;
1560
1632
  channel.bank = 0;
1561
- });
1633
+ }
1562
1634
  this.channels[9].bankMSB = 1;
1563
1635
  this.channels[9].bank = 128;
1564
1636
  }
1565
1637
  GM2SystemOn() {
1566
- this.channels.forEach((channel) => {
1638
+ for (let i = 0; i < this.channels.length; i++) {
1639
+ const channel = this.channels[i];
1567
1640
  channel.bankMSB = 121;
1568
1641
  channel.bankLSB = 0;
1569
1642
  channel.bank = 121 * 128;
1570
- });
1643
+ }
1571
1644
  this.channels[9].bankMSB = 120;
1572
1645
  this.channels[9].bank = 120 * 128;
1573
1646
  }
@@ -1876,7 +1949,7 @@ Object.defineProperty(Midy, "channelSettings", {
1876
1949
  currentBufferSource: null,
1877
1950
  volume: 100 / 127,
1878
1951
  pan: 64,
1879
- portamentoTime: 0,
1952
+ portamentoTime: 1, // sec
1880
1953
  filterResonance: 1,
1881
1954
  releaseTime: 1,
1882
1955
  attackTime: 1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marmooo/midy",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
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",
@@ -66,7 +66,6 @@ export class MidyGM1 {
66
66
  createChannels(audioContext: any): any[];
67
67
  createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
68
68
  createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
69
- convertToFloat32Array(uint8Array: any): Float32Array;
70
69
  scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
71
70
  getQueueIndex(second: any): number;
72
71
  playNotes(): Promise<any>;
@@ -76,8 +75,8 @@ export class MidyGM1 {
76
75
  instruments: Set<any>;
77
76
  timeline: any[];
78
77
  };
79
- stopChannelNotes(channelNumber: any, velocity: any, stopPedal: any): Promise<void>;
80
- stopNotes(velocity: any, stopPedal: any): Promise<any[]>;
78
+ stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
79
+ stopNotes(velocity: any, force: any): Promise<any[]>;
81
80
  start(): Promise<void>;
82
81
  stop(): void;
83
82
  pause(): void;
@@ -99,10 +98,11 @@ export class MidyGM1 {
99
98
  createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
100
99
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
101
100
  noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
102
- scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
103
- releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
101
+ stopNote(stopTime: any, endTime: any, scheduledNotes: any, index: any): Promise<any>;
102
+ scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, force: any): void;
103
+ releaseNote(channelNumber: any, noteNumber: any, velocity: any): void;
104
104
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
105
- handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
105
+ handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<void>;
106
106
  handleProgramChange(channelNumber: any, program: any): void;
107
107
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
108
108
  setPitchBend(channelNumber: any, pitchBend: any): void;
@@ -131,7 +131,7 @@ export class MidyGM1 {
131
131
  setPan(channelNumber: any, pan: any): void;
132
132
  setExpression(channelNumber: any, expression: any): void;
133
133
  dataEntryLSB(channelNumber: any, value: any): void;
134
- updateChannelGain(channel: any): void;
134
+ updateChannelVolume(channel: any): void;
135
135
  setSustainPedal(channelNumber: any, value: any): void;
136
136
  limitData(channel: any, minMSB: any, maxMSB: any, minLSB: any, maxLSB: any): void;
137
137
  limitDataMSB(channel: any, minMSB: any, maxMSB: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAwBA;IAmBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAOC;IA/CD,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;IAyBhB,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,sCAGC;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,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAaC;IAED,kDAKC;IAED,iEAOC;IAED,8CAKC;IAED,yDAMC;IAED,gDAKC;IAED,6DAMC;IAED,+CAEC;IAED,8CAEC;IAED,+CAEC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAnjCD;IAUE,gFAKC;IAdD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAChB,gBAAW;IACX,kBAAa;IAGX,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
1
+ {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAwBA;IAmBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAOC;IA/CD,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;IAyBhB,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,sCAGC;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,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAaC;IAED,kDAKC;IAED,iEAOC;IAED,8CAKC;IAED,yDAMC;IAED,gDAKC;IAED,6DAMC;IAED,+CAEC;IAED,8CAEC;IAED,+CAEC;IAED,4DAgBC;IAED,oBASC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAnjCD;IAUE,gFAKC;IAdD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAChB,gBAAW;IACX,kBAAa;IAGX,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}