@marmooo/midy 0.3.7 → 0.3.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marmooo/midy",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
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",
@@ -22,7 +22,7 @@
22
22
  "test": "node test_runner.js"
23
23
  },
24
24
  "dependencies": {
25
- "@marmooo/soundfont-parser": "^0.1.3",
25
+ "@marmooo/soundfont-parser": "^0.1.4",
26
26
  "midi-file": "^1.2.4"
27
27
  },
28
28
  "devDependencies": {
@@ -1,8 +1,8 @@
1
1
  export class MidyGM1 {
2
2
  static channelSettings: {
3
+ scheduleIndex: number;
3
4
  detune: number;
4
5
  programNumber: number;
5
- bank: number;
6
6
  dataMSB: number;
7
7
  dataLSB: number;
8
8
  rpnMSB: number;
@@ -22,7 +22,7 @@ export class MidyGM1 {
22
22
  startTime: number;
23
23
  resumeTime: number;
24
24
  soundFonts: any[];
25
- soundFontTable: any[];
25
+ soundFontTable: never[][];
26
26
  voiceCounter: Map<any, any>;
27
27
  voiceCache: Map<any, any>;
28
28
  isPlaying: boolean;
@@ -39,6 +39,7 @@ export class MidyGM1 {
39
39
  masterVolume: any;
40
40
  scheduler: any;
41
41
  schedulerBuffer: any;
42
+ messageHandlers: any[];
42
43
  voiceParamsHandlers: {
43
44
  modLfoToPitch: (channel: any, note: any, scheduleTime: any) => void;
44
45
  vibLfoToPitch: (_channel: any, _note: any, _scheduleTime: any) => void;
@@ -53,7 +54,6 @@ export class MidyGM1 {
53
54
  };
54
55
  controlChangeHandlers: any[];
55
56
  channels: any[];
56
- initSoundFontTable(): any[];
57
57
  addSoundFont(soundFont: any): void;
58
58
  toUint8Array(input: any): Promise<Uint8Array<ArrayBuffer>>;
59
59
  loadSoundFont(input: any): Promise<void>;
@@ -68,13 +68,14 @@ export class MidyGM1 {
68
68
  createChannels(audioContext: any): any[];
69
69
  createAudioBuffer(voiceParams: any): Promise<any>;
70
70
  createBufferSource(voiceParams: any, audioBuffer: any): any;
71
- scheduleTimelineEvents(t: any, resumeTime: any, queueIndex: any): Promise<any>;
71
+ scheduleTimelineEvents(scheduleTime: any, queueIndex: any): Promise<any>;
72
72
  getQueueIndex(second: any): number;
73
73
  resetAllStates(): void;
74
74
  updateStates(queueIndex: any, nextQueueIndex: any): void;
75
75
  playNotes(): Promise<void>;
76
76
  ticksToSecond(ticks: any, secondsPerBeat: any): number;
77
77
  secondToTicks(second: any, secondsPerBeat: any): number;
78
+ getSoundFontId(channel: any): string;
78
79
  extractMidiData(midi: any): {
79
80
  instruments: Set<any>;
80
81
  timeline: any[];
@@ -115,7 +116,9 @@ export class MidyGM1 {
115
116
  findNoteOffIndex(channel: any, noteNumber: any): any;
116
117
  noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): void;
117
118
  releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
118
- handleMIDIMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<void>;
119
+ createMessageHandlers(): any[];
120
+ handleMessage(data: any, scheduleTime: any): void;
121
+ handleChannelMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<void>;
119
122
  setProgramChange(channelNumber: any, programNumber: any, _scheduleTime: any): void;
120
123
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any, scheduleTime: any): void;
121
124
  setPitchBend(channelNumber: any, value: any, scheduleTime: any): void;
@@ -172,7 +175,7 @@ export class MidyGM1 {
172
175
  GM1SystemOn(scheduleTime: any): void;
173
176
  handleUniversalRealTimeExclusiveMessage(data: any, scheduleTime: any): void;
174
177
  handleMasterVolumeSysEx(data: any, scheduleTime: any): void;
175
- setMasterVolume(volume: any, scheduleTime: any): void;
178
+ setMasterVolume(value: any, scheduleTime: any): void;
176
179
  handleSysEx(data: any, scheduleTime: any): void;
177
180
  scheduleTask(callback: any, scheduleTime: any): Promise<any>;
178
181
  }
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA4FA;IAyBE;;;;;;;;;;;MAWE;IAEF,+BAcC;IAnDD,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,4BAAyB;IACzB,0BAAuB;IACvB,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAgBnC,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IAMnD,4BAMC;IAED,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAcC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDAUC;IAED,4DASC;IAED,+EAkDC;IAED,mCAOC;IAED,uBAQC;IAED,yDA2BC;IAED,2BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgEC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAKC;IAED,uBAQC;IAED,wBAKC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,yDAQC;IAED,yEASC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDAsBC;IAED,kEAoBC;IAED,6FAyBC;IAED,oGAuCC;IAED,0EAiBC;IAED,kGAmCC;IAED,6FASC;IAED,gCASC;IAED,iEAoBC;IAED,qGAeC;IAED,6CAUC;IAED,qDAUC;IAED,qFASC;IAED,sFAeC;IAED,oGA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAWC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MAiCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDASC;IAED,iFAKC;IAED,oEAKC;IAED;;;MAMC;IAED,8DAKC;IAED,4EAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,2DAMC;IAED,uDAkBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,iEAMC;IAED,uEAQC;IAED,mEAKC;IAED,yEAQC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCAWC;IAED,4EAaC;IAED,4DAGC;IAED,sDASC;IAED,gDAYC;IAGD,6DAgBC;CACF;AAhiDD;IAWE,0FAMC;IAhBD,cAAW;IACX,gBAAe;IACf,kBAAa;IACb,gBAAW;IACX,iBAAY;IACZ,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
1
+ {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA4FA;IAyBE;;;;;;;;;;;MAWE;IAEF,+BAeC;IApDD,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,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAgBnC,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,8DAWC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDAUC;IAED,4DASC;IAED,yEAqDC;IAED,mCAOC;IAED,uBAQC;IAED,yDA2BC;IAED,2BAwCC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAKC;IAED,uBAQC;IAED,wBAKC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,yDAQC;IAED,yEASC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDAsBC;IAED,kEAoBC;IAED,6FAyBC;IAED,oGAuCC;IAED,0EAiBC;IAED,kGAgCC;IAED,6FASC;IAED,gCASC;IAED,iEAoBC;IAED,qGAeC;IAED,6CAUC;IAED,qDAUC;IAED,qFASC;IAED,sFAeC;IAED,+BAmBC;IAED,kDAOC;IAED,uGA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAWC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MAiCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDASC;IAED,iFAKC;IAED,oEAKC;IAED;;;MAMC;IAED,8DAKC;IAED,4EAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,2DAMC;IAED,uDAkBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,iEAMC;IAED,uEAQC;IAED,mEAKC;IAED,yEAQC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCASC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF;AAtiDD;IAWE,0FAMC;IAhBD,cAAW;IACX,gBAAe;IACf,kBAAa;IACb,gBAAW;IACX,iBAAY;IACZ,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
@@ -203,7 +203,7 @@ class MidyGM1 {
203
203
  enumerable: true,
204
204
  configurable: true,
205
205
  writable: true,
206
- value: this.initSoundFontTable()
206
+ value: Array.from({ length: 128 }, () => [])
207
207
  });
208
208
  Object.defineProperty(this, "voiceCounter", {
209
209
  enumerable: true,
@@ -284,6 +284,7 @@ class MidyGM1 {
284
284
  length: 1,
285
285
  sampleRate: audioContext.sampleRate,
286
286
  });
287
+ this.messageHandlers = this.createMessageHandlers();
287
288
  this.voiceParamsHandlers = this.createVoiceParamsHandlers();
288
289
  this.controlChangeHandlers = this.createControlChangeHandlers();
289
290
  this.channels = this.createChannels(audioContext);
@@ -291,21 +292,14 @@ class MidyGM1 {
291
292
  this.scheduler.connect(audioContext.destination);
292
293
  this.GM1SystemOn();
293
294
  }
294
- initSoundFontTable() {
295
- const table = new Array(128);
296
- for (let i = 0; i < 128; i++) {
297
- table[i] = new Map();
298
- }
299
- return table;
300
- }
301
295
  addSoundFont(soundFont) {
302
296
  const index = this.soundFonts.length;
303
297
  this.soundFonts.push(soundFont);
304
298
  const presetHeaders = soundFont.parsed.presetHeaders;
299
+ const soundFontTable = this.soundFontTable;
305
300
  for (let i = 0; i < presetHeaders.length; i++) {
306
- const presetHeader = presetHeaders[i];
307
- const banks = this.soundFontTable[presetHeader.preset];
308
- banks.set(presetHeader.bank, index);
301
+ const { preset, bank } = presetHeaders[i];
302
+ soundFontTable[preset][bank] = index;
309
303
  }
310
304
  }
311
305
  async toUint8Array(input) {
@@ -383,13 +377,16 @@ class MidyGM1 {
383
377
  this.GM1SystemOn();
384
378
  }
385
379
  getVoiceId(channel, noteNumber, velocity) {
386
- const bankNumber = this.calcBank(channel);
387
- const soundFontIndex = this.soundFontTable[channel.programNumber]
388
- .get(bankNumber);
380
+ const programNumber = channel.programNumber;
381
+ const bankTable = this.soundFontTable[programNumber];
382
+ if (!bankTable)
383
+ return;
384
+ const bank = channel.isDrum ? 128 : 0;
385
+ const soundFontIndex = bankTable[bank];
389
386
  if (soundFontIndex === undefined)
390
387
  return;
391
388
  const soundFont = this.soundFonts[soundFontIndex];
392
- const voice = soundFont.getVoice(bankNumber, channel.programNumber, noteNumber, velocity);
389
+ const voice = soundFont.getVoice(bank, programNumber, noteNumber, velocity);
393
390
  const { instrument, sampleID } = voice.generators;
394
391
  return soundFontIndex * (2 ** 32) + (instrument << 16) + sampleID;
395
392
  }
@@ -438,13 +435,16 @@ class MidyGM1 {
438
435
  }
439
436
  return bufferSource;
440
437
  }
441
- async scheduleTimelineEvents(t, resumeTime, queueIndex) {
442
- while (queueIndex < this.timeline.length) {
443
- const event = this.timeline[queueIndex];
444
- if (event.startTime > t + this.lookAhead)
438
+ async scheduleTimelineEvents(scheduleTime, queueIndex) {
439
+ const timeOffset = this.resumeTime - this.startTime;
440
+ const lookAheadCheckTime = scheduleTime + timeOffset + this.lookAhead;
441
+ const schedulingOffset = this.startDelay - timeOffset;
442
+ const timeline = this.timeline;
443
+ while (queueIndex < timeline.length) {
444
+ const event = timeline[queueIndex];
445
+ if (lookAheadCheckTime < event.startTime)
445
446
  break;
446
- const delay = this.startDelay - resumeTime;
447
- const startTime = event.startTime + delay;
447
+ const startTime = event.startTime + schedulingOffset;
448
448
  switch (event.type) {
449
449
  case "noteOn":
450
450
  await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, startTime);
@@ -516,13 +516,11 @@ class MidyGM1 {
516
516
  this.isPaused = false;
517
517
  this.startTime = this.audioContext.currentTime;
518
518
  let queueIndex = this.getQueueIndex(this.resumeTime);
519
- let resumeTime = this.resumeTime - this.startTime;
520
519
  let finished = false;
521
520
  this.notePromises = [];
522
521
  while (queueIndex < this.timeline.length) {
523
522
  const now = this.audioContext.currentTime;
524
- const t = now + resumeTime;
525
- queueIndex = await this.scheduleTimelineEvents(t, resumeTime, queueIndex);
523
+ queueIndex = await this.scheduleTimelineEvents(now, queueIndex);
526
524
  if (this.isPausing) {
527
525
  await this.stopNotes(0, true, now);
528
526
  await this.audioContext.suspend();
@@ -541,7 +539,6 @@ class MidyGM1 {
541
539
  const nextQueueIndex = this.getQueueIndex(this.resumeTime);
542
540
  this.updateStates(queueIndex, nextQueueIndex);
543
541
  queueIndex = nextQueueIndex;
544
- resumeTime = this.resumeTime - this.startTime;
545
542
  this.isSeeking = false;
546
543
  continue;
547
544
  }
@@ -560,16 +557,16 @@ class MidyGM1 {
560
557
  secondToTicks(second, secondsPerBeat) {
561
558
  return second * this.ticksPerBeat / secondsPerBeat;
562
559
  }
560
+ getSoundFontId(channel) {
561
+ const programNumber = channel.programNumber;
562
+ const bank = channel.isDrum ? "128" : "000";
563
+ const program = programNumber.toString().padStart(3, "0");
564
+ return `${bank}:${program}`;
565
+ }
563
566
  extractMidiData(midi) {
564
567
  const instruments = new Set();
565
568
  const timeline = [];
566
- const tmpChannels = new Array(this.channels.length);
567
- for (let i = 0; i < tmpChannels.length; i++) {
568
- tmpChannels[i] = {
569
- programNumber: -1,
570
- bank: this.channels[i].bank,
571
- };
572
- }
569
+ const channels = this.channels;
573
570
  for (let i = 0; i < midi.tracks.length; i++) {
574
571
  const track = midi.tracks[i];
575
572
  let currentTicks = 0;
@@ -579,17 +576,15 @@ class MidyGM1 {
579
576
  event.ticks = currentTicks;
580
577
  switch (event.type) {
581
578
  case "noteOn": {
582
- const channel = tmpChannels[event.channel];
583
- if (channel.programNumber < 0) {
584
- instruments.add(`${channel.bank}:0`);
585
- channel.programNumber = 0;
586
- }
579
+ const channel = channels[event.channel];
580
+ instruments.add(this.getSoundFontId(channel));
587
581
  break;
588
582
  }
589
583
  case "programChange": {
590
- const channel = tmpChannels[event.channel];
591
- channel.programNumber = event.programNumber;
592
- instruments.add(`${channel.bankNumber}:${channel.programNumber}`);
584
+ const channel = channels[event.channel];
585
+ this.setProgramChange(event.channel, event.programNumber);
586
+ instruments.add(this.getSoundFontId(channel));
587
+ break;
593
588
  }
594
589
  }
595
590
  delete event.deltaTime;
@@ -895,13 +890,16 @@ class MidyGM1 {
895
890
  }
896
891
  async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
897
892
  const channel = this.channels[channelNumber];
898
- const bankNumber = channel.bank;
899
- const soundFontIndex = this.soundFontTable[channel.programNumber]
900
- .get(bankNumber);
893
+ const programNumber = channel.programNumber;
894
+ const bankTable = this.soundFontTable[programNumber];
895
+ if (!bankTable)
896
+ return;
897
+ const bank = channel.isDrum ? 128 : 0;
898
+ const soundFontIndex = bankTable[bank];
901
899
  if (soundFontIndex === undefined)
902
900
  return;
903
901
  const soundFont = this.soundFonts[soundFontIndex];
904
- const voice = soundFont.getVoice(bankNumber, channel.programNumber, noteNumber, velocity);
902
+ const voice = soundFont.getVoice(bank, programNumber, noteNumber, velocity);
905
903
  if (!voice)
906
904
  return;
907
905
  const note = await this.createNote(channel, voice, noteNumber, velocity, startTime);
@@ -1003,7 +1001,26 @@ class MidyGM1 {
1003
1001
  channel.sustainNotes = [];
1004
1002
  return promises;
1005
1003
  }
1006
- handleMIDIMessage(statusByte, data1, data2, scheduleTime) {
1004
+ createMessageHandlers() {
1005
+ const handlers = new Array(256);
1006
+ // Channel Message
1007
+ handlers[0x80] = (data, scheduleTime) => this.noteOff(data[0] & 0x0F, data[1], data[2], scheduleTime);
1008
+ handlers[0x90] = (data, scheduleTime) => this.noteOn(data[0] & 0x0F, data[1], data[2], scheduleTime);
1009
+ handlers[0xB0] = (data, scheduleTime) => this.setControlChange(data[0] & 0x0F, data[1], data[2], scheduleTime);
1010
+ handlers[0xC0] = (data, scheduleTime) => this.setProgramChange(data[0] & 0x0F, data[1], scheduleTime);
1011
+ handlers[0xE0] = (data, scheduleTime) => this.handlePitchBendMessage(data[0] & 0x0F, data[1], data[2], scheduleTime);
1012
+ return handlers;
1013
+ }
1014
+ handleMessage(data, scheduleTime) {
1015
+ const status = data[0];
1016
+ if (status === 0xF0) {
1017
+ return this.handleSysEx(data.subarray(1), scheduleTime);
1018
+ }
1019
+ const handler = this.messageHandlers[status];
1020
+ if (handler)
1021
+ handler(data, scheduleTime);
1022
+ }
1023
+ handleChannelMessage(statusByte, data1, data2, scheduleTime) {
1007
1024
  const channelNumber = statusByte & 0x0F;
1008
1025
  const messageType = statusByte & 0xF0;
1009
1026
  switch (messageType) {
@@ -1431,10 +1448,8 @@ class MidyGM1 {
1431
1448
  for (let i = 0; i < this.channels.length; i++) {
1432
1449
  this.allSoundOff(i, 0, scheduleTime);
1433
1450
  const channel = this.channels[i];
1434
- channel.bank = 0;
1435
1451
  channel.isDrum = false;
1436
1452
  }
1437
- this.channels[9].bank = 128;
1438
1453
  this.channels[9].isDrum = true;
1439
1454
  }
1440
1455
  handleUniversalRealTimeExclusiveMessage(data, scheduleTime) {
@@ -1455,16 +1470,11 @@ class MidyGM1 {
1455
1470
  const volume = (data[5] * 128 + data[4]) / 16383;
1456
1471
  this.setMasterVolume(volume, scheduleTime);
1457
1472
  }
1458
- setMasterVolume(volume, scheduleTime) {
1473
+ setMasterVolume(value, scheduleTime) {
1459
1474
  scheduleTime ??= this.audioContext.currentTime;
1460
- if (volume < 0 && 1 < volume) {
1461
- console.error("Master Volume is out of range");
1462
- }
1463
- else {
1464
- this.masterVolume.gain
1465
- .cancelScheduledValues(scheduleTime)
1466
- .setValueAtTime(volume * volume, scheduleTime);
1467
- }
1475
+ this.masterVolume.gain
1476
+ .cancelScheduledValues(scheduleTime)
1477
+ .setValueAtTime(value * value, scheduleTime);
1468
1478
  }
1469
1479
  handleSysEx(data, scheduleTime) {
1470
1480
  switch (data[0]) {
@@ -1502,9 +1512,9 @@ Object.defineProperty(MidyGM1, "channelSettings", {
1502
1512
  configurable: true,
1503
1513
  writable: true,
1504
1514
  value: {
1515
+ scheduleIndex: 0,
1505
1516
  detune: 0,
1506
1517
  programNumber: 0,
1507
- bank: 0,
1508
1518
  dataMSB: 0,
1509
1519
  dataLSB: 0,
1510
1520
  rpnMSB: 127,
@@ -3,7 +3,6 @@ export class MidyGM2 {
3
3
  scheduleIndex: number;
4
4
  detune: number;
5
5
  programNumber: number;
6
- bank: number;
7
6
  bankMSB: number;
8
7
  bankLSB: number;
9
8
  dataMSB: number;
@@ -34,13 +33,15 @@ export class MidyGM2 {
34
33
  numChannels: number;
35
34
  ticksPerBeat: number;
36
35
  totalTime: number;
36
+ lastActiveSensing: number;
37
+ activeSensingThreshold: number;
37
38
  noteCheckInterval: number;
38
39
  lookAhead: number;
39
40
  startDelay: number;
40
41
  startTime: number;
41
42
  resumeTime: number;
42
43
  soundFonts: any[];
43
- soundFontTable: any[];
44
+ soundFontTable: never[][];
44
45
  voiceCounter: Map<any, any>;
45
46
  voiceCache: Map<any, any>;
46
47
  isPlaying: boolean;
@@ -58,6 +59,7 @@ export class MidyGM2 {
58
59
  masterVolume: any;
59
60
  scheduler: any;
60
61
  schedulerBuffer: any;
62
+ messageHandlers: any[];
61
63
  voiceParamsHandlers: {
62
64
  modLfoToPitch: (channel: any, note: any, scheduleTime: any) => void;
63
65
  vibLfoToPitch: (channel: any, note: any, scheduleTime: any) => void;
@@ -71,6 +73,7 @@ export class MidyGM2 {
71
73
  freqVibLFO: (channel: any, note: any, scheduleTime: any) => void;
72
74
  };
73
75
  controlChangeHandlers: any[];
76
+ keyBasedControllerHandlers: any[];
74
77
  channels: any[];
75
78
  reverbEffect: {
76
79
  input: any;
@@ -85,7 +88,6 @@ export class MidyGM2 {
85
88
  delayNodes: any[];
86
89
  feedbackGains: any[];
87
90
  };
88
- initSoundFontTable(): any[];
89
91
  addSoundFont(soundFont: any): void;
90
92
  toUint8Array(input: any): Promise<Uint8Array<ArrayBuffer>>;
91
93
  loadSoundFont(input: any): Promise<void>;
@@ -102,13 +104,14 @@ export class MidyGM2 {
102
104
  createAudioBuffer(voiceParams: any): Promise<any>;
103
105
  isLoopDrum(channel: any, noteNumber: any): boolean;
104
106
  createBufferSource(channel: any, noteNumber: any, voiceParams: any, audioBuffer: any): any;
105
- scheduleTimelineEvents(t: any, resumeTime: any, queueIndex: any): Promise<any>;
107
+ scheduleTimelineEvents(scheduleTime: any, queueIndex: any): Promise<any>;
106
108
  getQueueIndex(second: any): number;
107
109
  resetAllStates(): void;
108
110
  updateStates(queueIndex: any, nextQueueIndex: any): void;
109
111
  playNotes(): Promise<void>;
110
112
  ticksToSecond(ticks: any, secondsPerBeat: any): number;
111
113
  secondToTicks(second: any, secondsPerBeat: any): number;
114
+ getSoundFontId(channel: any): string;
112
115
  extractMidiData(midi: any): {
113
116
  instruments: Set<any>;
114
117
  timeline: any[];
@@ -172,7 +175,6 @@ export class MidyGM2 {
172
175
  startVibrato(channel: any, note: any, scheduleTime: any): void;
173
176
  getAudioBuffer(channel: any, noteNumber: any, velocity: any, voiceParams: any): Promise<any>;
174
177
  createNote(channel: any, voice: any, noteNumber: any, velocity: any, startTime: any): Promise<Note>;
175
- calcBank(channel: any): any;
176
178
  handleExclusiveClass(note: any, channelNumber: any, startTime: any): void;
177
179
  handleDrumExclusiveClass(note: any, channelNumber: any, startTime: any): void;
178
180
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
@@ -185,7 +187,9 @@ export class MidyGM2 {
185
187
  noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): void;
186
188
  releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
187
189
  releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
188
- handleMIDIMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<void>;
190
+ createMessageHandlers(): any[];
191
+ handleMessage(data: any, scheduleTime: any): void;
192
+ activeSensing(): void;
189
193
  setProgramChange(channelNumber: any, programNumber: any, _scheduleTime: any): void;
190
194
  setChannelPressure(channelNumber: any, value: any, scheduleTime: any): void;
191
195
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any, scheduleTime: any): void;
@@ -233,6 +237,7 @@ export class MidyGM2 {
233
237
  updateChannelVolume(channel: any, scheduleTime: any): void;
234
238
  updateKeyBasedVolume(channel: any, keyNumber: any, scheduleTime: any): void;
235
239
  setSustainPedal(channelNumber: any, value: any, scheduleTime: any): void;
240
+ isPortamento(channel: any, note: any): boolean;
236
241
  setPortamento(channelNumber: any, value: any, scheduleTime: any): void;
237
242
  setSostenutoPedal(channelNumber: any, value: any, scheduleTime: any): void;
238
243
  getSoftPedalFactor(channel: any, note: any): number;
@@ -266,7 +271,7 @@ export class MidyGM2 {
266
271
  GM2SystemOn(scheduleTime: any): void;
267
272
  handleUniversalRealTimeExclusiveMessage(data: any, scheduleTime: any): void;
268
273
  handleMasterVolumeSysEx(data: any, scheduleTime: any): void;
269
- setMasterVolume(volume: any, scheduleTime: any): void;
274
+ setMasterVolume(value: any, scheduleTime: any): void;
270
275
  handleMasterFineTuningSysEx(data: any, scheduleTime: any): void;
271
276
  setMasterFineTuning(value: any, scheduleTime: any): void;
272
277
  handleMasterCoarseTuningSysEx(data: any, scheduleTime: any): void;
@@ -302,6 +307,7 @@ export class MidyGM2 {
302
307
  setControlChangeEffects(channel: any, controllerType: any, scheduleTime: any): void;
303
308
  handleControlChangeSysEx(data: any, scheduleTime: any): void;
304
309
  getKeyBasedValue(channel: any, keyNumber: any, controllerType: any): any;
310
+ createKeyBasedControllerHandlers(): any[];
305
311
  handleKeyBasedInstrumentControlSysEx(data: any, scheduleTime: any): void;
306
312
  handleSysEx(data: any, scheduleTime: any): void;
307
313
  scheduleTask(callback: any, scheduleTime: any): Promise<any>;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAkJA;IA0CE;;;;;;;;;;;;;;;MAeE;IAEF,+BAkBC;IA5ED,aAAa;IACb,yBAAqB;IACrB,2BAAuB;IACvB;;;;MAIE;IACF;;;;;;MAME;IACF,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,4BAAyB;IACzB,0BAAuB;IACvB,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAoBA,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IACjD;;;kBAAyD;IACzD;;;;;;;;MAAyD;IAQ3D,4BAMC;IAED,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAcC;IAED;;;;MAeC;IAED,sCAKC;IAED,yCAqBC;IAED,kDAUC;IAED,mDAIC;IAED,2FAWC;IAED,+EAqDC;IAED,mCAOC;IAED,uBAQC;IAED,yDA2BC;IAED,2BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAoGC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAKC;IAED,uBAQC;IAED,wBAKC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,yDAQC;IAED,yEASC;IAED,kFAuBC;IAED;;;;MASC;IAED,gFAUC;IAED,mFAYC;IAED,sGAcC;IAID;;;MA8BC;IAED;;;kBA6BC;IAED;;;;;;;;MA0CC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAkBC;IAED,6CAEC;IAED,2DAIC;IAED,+DAgBC;IAED,mDAIC;IAED,2CAoDC;IAED,8EAWC;IAED,oEAgBC;IAED,+DAKC;IAED,qDAoBC;IAED,6CAIC;IAED,8EAoBC;IAED,oEAwBC;IAED,kEAoBC;IAED,+DAeC;IAED,6FAyBC;IAED,oGAiEC;IAED,4BAYC;IAED,0EAiBC;IAED,8EAoBC;IAED,kGAiDC;IAED,6FASC;IAED,gCAmBC;IAED,iEAoBC;IAED,qGAuBC;IAED,6CAUC;IAED,qDAUC;IAED,qFASC;IAED,sFAeC;IAED,wFAkBC;IAED,oGA6BC;IAED,mFAeC;IAED,4EAgBC;IAED,wFAGC;IAED,sEAWC;IAED,mEAYC;IAED,mEAYC;IAED,sEAMC;IAED,oEAQC;IAED,gEAyBC;IAED,gEAyBC;IAED,gCAKC;IAED,kDAKC;IAED,gEAMC;IAED,8CAOC;IAED;;;;;;;;;;;MAiDC;IAED,oFAOC;IAED,6EA+BC;IAED,qCA2BC;IAED,+FAYC;IAED,+CAEC;IAED,wDASC;IAED,iFAMC;IAED,wDAkBC;IAED,oFAMC;IAED,oEAWC;IAED;;;MAMC;IAED,8DAWC;IAED,4EAKC;IAED,+CAEC;IAED,sEAGC;IAED,2DAUC;IAED,4EAoBC;IAED,yEAYC;IAED,uEAMC;IAED,2EAcC;IAED,oDAEC;IAED,0EAeC;IAED,sFAQC;IAED,sFAQC;IAED,kFAeC;IAED,2DAMC;IAED,uDAqBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAWC;IAED,iEAMC;IAED,uEASC;IAED,mEAKC;IAED,yEASC;IAED,2EAKC;IAED,iFAMC;IAED,gFAGC;IAED,6CAwBC;IAGD,8EAoCC;IAED,gFAGC;IAED,iEAEC;IAED,gEAEC;IAED,gEAIC;IAED,gEAIC;IAED,+EAgCC;IAED,qCAcC;IAED,qCAcC;IAED,4EA4CC;IAED,4DAGC;IAED,sDASC;IAED,gEAIC;IAED,yDAWC;IAED,kEAGC;IAED,2DAWC;IAED,sEAeC;IAED,4CAOC;IAED,+BAIC;IAED,qDAiBC;IAED,gCAGC;IAED,kCAEC;IA6BD,4CAEC;IAED,+DAaC;IAED,kDAiBC;IAED,2GAKC;IAED,sDAIC;IAED,qCAEC;IAED,uDAMC;IAED,sCAEC;IAED,uDASC;IAED,sCAEC;IAED,2DAqBC;IAED,0CAEC;IAED,mCAeC;IAED,2FAgBC;IAED,6CAMC;IAED,0CAMC;IAED,uCAMC;IAED,wCAMC;IAED,2CAMC;IAED,yEAgBC;IAED,wEAaC;IAED,2CAIC;IAED,oFAOC;IAED,6DAcC;IAED,yEAIC;IAED,yEAgCC;IAED,gDAYC;IAGD,6DAgBC;CACF;AAj6FD;IAgBE,0FAMC;IArBD,cAAW;IACX,gBAAe;IACf,kBAAa;IACb,gBAAW;IACX,iBAAY;IACZ,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAChB,gBAAW;IACX,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,6BAA0B;IAGxB,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
1
+ {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}