@marmooo/midy 0.3.2 → 0.3.3

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.
@@ -11,6 +11,12 @@ class Note {
11
11
  writable: true,
12
12
  value: -1
13
13
  });
14
+ Object.defineProperty(this, "ending", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: false
19
+ });
14
20
  Object.defineProperty(this, "bufferSource", {
15
21
  enumerable: true,
16
22
  configurable: true,
@@ -292,17 +298,37 @@ class MidyGM1 {
292
298
  }
293
299
  }
294
300
  }
295
- async loadSoundFont(soundFontUrl) {
296
- const response = await fetch(soundFontUrl);
297
- const arrayBuffer = await response.arrayBuffer();
298
- const parsed = (0, soundfont_parser_1.parse)(new Uint8Array(arrayBuffer));
301
+ async loadSoundFont(input) {
302
+ let uint8Array;
303
+ if (typeof input === "string") {
304
+ const response = await fetch(input);
305
+ const arrayBuffer = await response.arrayBuffer();
306
+ uint8Array = new Uint8Array(arrayBuffer);
307
+ }
308
+ else if (input instanceof Uint8Array) {
309
+ uint8Array = input;
310
+ }
311
+ else {
312
+ throw new TypeError("input must be a URL string or Uint8Array");
313
+ }
314
+ const parsed = (0, soundfont_parser_1.parse)(uint8Array);
299
315
  const soundFont = new soundfont_parser_1.SoundFont(parsed);
300
316
  this.addSoundFont(soundFont);
301
317
  }
302
- async loadMIDI(midiUrl) {
303
- const response = await fetch(midiUrl);
304
- const arrayBuffer = await response.arrayBuffer();
305
- const midi = (0, midi_file_1.parseMidi)(new Uint8Array(arrayBuffer));
318
+ async loadMIDI(input) {
319
+ let uint8Array;
320
+ if (typeof input === "string") {
321
+ const response = await fetch(input);
322
+ const arrayBuffer = await response.arrayBuffer();
323
+ uint8Array = new Uint8Array(arrayBuffer);
324
+ }
325
+ else if (input instanceof Uint8Array) {
326
+ uint8Array = input;
327
+ }
328
+ else {
329
+ throw new TypeError("input must be a URL string or Uint8Array");
330
+ }
331
+ const midi = (0, midi_file_1.parseMidi)(uint8Array);
306
332
  this.ticksPerBeat = midi.header.ticksPerBeat;
307
333
  const midiData = this.extractMidiData(midi);
308
334
  this.instruments = midiData.instruments;
@@ -384,12 +410,13 @@ class MidyGM1 {
384
410
  const delay = this.startDelay - resumeTime;
385
411
  const startTime = event.startTime + delay;
386
412
  switch (event.type) {
387
- case "noteOn": {
388
- const noteOffEvent = {
389
- ...event.noteOffEvent,
390
- startTime: event.noteOffEvent.startTime + delay,
391
- };
392
- await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, startTime, noteOffEvent);
413
+ case "noteOn":
414
+ await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, startTime);
415
+ break;
416
+ case "noteOff": {
417
+ const notePromise = this.scheduleNoteOff(event.channel, event.noteNumber, event.velocity, startTime, false);
418
+ if (notePromise)
419
+ this.notePromises.push(notePromise);
393
420
  break;
394
421
  }
395
422
  case "controller":
@@ -488,6 +515,7 @@ class MidyGM1 {
488
515
  return `${programNumber}:${noteNumber}:${velocity}`;
489
516
  }
490
517
  extractMidiData(midi) {
518
+ this.audioBufferCounter.clear();
491
519
  const instruments = new Set();
492
520
  const timeline = [];
493
521
  const tmpChannels = new Array(this.channels.length);
@@ -551,38 +579,13 @@ class MidyGM1 {
551
579
  prevTempoTicks = event.ticks;
552
580
  }
553
581
  }
554
- const activeNotes = new Array(this.channels.length * 128);
555
- for (let i = 0; i < activeNotes.length; i++) {
556
- activeNotes[i] = [];
557
- }
558
- for (let i = 0; i < timeline.length; i++) {
559
- const event = timeline[i];
560
- switch (event.type) {
561
- case "noteOn": {
562
- const index = event.channel * 128 + event.noteNumber;
563
- activeNotes[index].push(event);
564
- break;
565
- }
566
- case "noteOff": {
567
- const index = event.channel * 128 + event.noteNumber;
568
- const noteOn = activeNotes[index].pop();
569
- if (noteOn) {
570
- noteOn.noteOffEvent = event;
571
- }
572
- else {
573
- const eventString = JSON.stringify(event, null, 2);
574
- console.warn(`noteOff without matching noteOn: ${eventString}`);
575
- }
576
- }
577
- }
578
- }
579
582
  return { instruments, timeline };
580
583
  }
581
584
  stopActiveNotes(channelNumber, velocity, force, scheduleTime) {
582
585
  const channel = this.channels[channelNumber];
583
586
  const promises = [];
584
587
  this.processActiveNotes(channel, scheduleTime, (note) => {
585
- const promise = this.scheduleNoteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force, undefined);
588
+ const promise = this.scheduleNoteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force);
586
589
  this.notePromises.push(promise);
587
590
  promises.push(promise);
588
591
  });
@@ -592,7 +595,7 @@ class MidyGM1 {
592
595
  const channel = this.channels[channelNumber];
593
596
  const promises = [];
594
597
  this.processScheduledNotes(channel, (note) => {
595
- const promise = this.scheduleNoteOff(channelNumber, note, velocity, scheduleTime, force);
598
+ const promise = this.scheduleNoteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force);
596
599
  this.notePromises.push(promise);
597
600
  promises.push(promise);
598
601
  });
@@ -669,9 +672,6 @@ class MidyGM1 {
669
672
  continue;
670
673
  if (note.ending)
671
674
  continue;
672
- const noteOffEvent = note.noteOffEvent;
673
- if (noteOffEvent && noteOffEvent.startTime < scheduleTime)
674
- continue;
675
675
  if (scheduleTime < note.startTime)
676
676
  continue;
677
677
  callback(note);
@@ -841,7 +841,7 @@ class MidyGM1 {
841
841
  if (prev) {
842
842
  const [prevNote, prevChannelNumber] = prev;
843
843
  if (prevNote && !prevNote.ending) {
844
- this.scheduleNoteOff(prevChannelNumber, prevNote, 0, // velocity,
844
+ this.scheduleNoteOff(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
845
845
  startTime, true);
846
846
  }
847
847
  }
@@ -869,12 +869,6 @@ class MidyGM1 {
869
869
  const scheduledNotes = channel.scheduledNotes;
870
870
  note.index = scheduledNotes.length;
871
871
  scheduledNotes.push(note);
872
- if (noteOffEvent) {
873
- const notePromise = this.scheduleNoteOff(channelNumber, note, noteOffEvent.velocity, noteOffEvent.startTime, false);
874
- if (notePromise) {
875
- this.notePromises.push(notePromise);
876
- }
877
- }
878
872
  }
879
873
  noteOn(channelNumber, noteNumber, velocity, scheduleTime) {
880
874
  scheduleTime ??= this.audioContext.currentTime;
@@ -890,34 +884,36 @@ class MidyGM1 {
890
884
  note.modulationLFO.stop();
891
885
  }
892
886
  }
893
- stopNote(channel, note, endTime, stopTime) {
887
+ releaseNote(channel, note, endTime) {
888
+ const volRelease = endTime + note.voiceParams.volRelease;
889
+ const modRelease = endTime + note.voiceParams.modRelease;
890
+ const stopTime = Math.min(volRelease, modRelease);
891
+ note.filterNode.frequency
892
+ .cancelScheduledValues(endTime)
893
+ .linearRampToValueAtTime(0, modRelease);
894
894
  note.volumeEnvelopeNode.gain
895
895
  .cancelScheduledValues(endTime)
896
- .linearRampToValueAtTime(0, stopTime);
897
- note.ending = true;
898
- this.scheduleTask(() => {
899
- note.bufferSource.loop = false;
900
- }, stopTime);
896
+ .linearRampToValueAtTime(0, volRelease);
901
897
  return new Promise((resolve) => {
902
- note.bufferSource.onended = () => {
903
- channel.scheduledNotes[note.index] = undefined;
898
+ this.scheduleTask(() => {
899
+ const bufferSource = note.bufferSource;
900
+ bufferSource.loop = false;
901
+ bufferSource.stop(stopTime);
904
902
  this.disconnectNote(note);
903
+ channel.scheduledNotes[note.index] = undefined;
905
904
  resolve();
906
- };
907
- note.bufferSource.stop(stopTime);
905
+ }, stopTime);
908
906
  });
909
907
  }
910
- scheduleNoteOff(channelNumber, note, _velocity, endTime, force) {
908
+ scheduleNoteOff(channelNumber, noteNumber, _velocity, endTime, force) {
911
909
  const channel = this.channels[channelNumber];
912
910
  if (!force && 0.5 <= channel.state.sustainPedal)
913
911
  return;
914
- const volRelease = endTime + note.voiceParams.volRelease;
915
- const modRelease = endTime + note.voiceParams.modRelease;
916
- note.filterNode.frequency
917
- .cancelScheduledValues(endTime)
918
- .linearRampToValueAtTime(0, modRelease);
919
- const stopTime = Math.min(volRelease, modRelease);
920
- return this.stopNote(channel, note, endTime, stopTime);
912
+ const note = this.findNoteOffTarget(channel, noteNumber);
913
+ if (!note)
914
+ return;
915
+ note.ending = true;
916
+ this.releaseNote(channel, note, endTime);
921
917
  }
922
918
  findNoteOffTarget(channel, noteNumber) {
923
919
  const scheduledNotes = channel.scheduledNotes;
@@ -934,16 +930,14 @@ class MidyGM1 {
934
930
  }
935
931
  noteOff(channelNumber, noteNumber, velocity, scheduleTime) {
936
932
  scheduleTime ??= this.audioContext.currentTime;
937
- const channel = this.channels[channelNumber];
938
- const note = this.findNoteOffTarget(channel, noteNumber);
939
- return this.scheduleNoteOff(channelNumber, note, velocity, scheduleTime, false);
933
+ return this.scheduleNoteOff(channelNumber, noteNumber, velocity, scheduleTime, false);
940
934
  }
941
935
  releaseSustainPedal(channelNumber, halfVelocity, scheduleTime) {
942
936
  const velocity = halfVelocity * 2;
943
937
  const channel = this.channels[channelNumber];
944
938
  const promises = [];
945
939
  for (let i = 0; i < channel.sustainNotes.length; i++) {
946
- const promise = this.scheduleNoteOff(channelNumber, channel.sustainNotes[i], velocity, scheduleTime);
940
+ const promise = this.scheduleNoteOff(channelNumber, channel.sustainNotes[i].noteNumber, velocity, scheduleTime);
947
941
  promises.push(promise);
948
942
  }
949
943
  channel.sustainNotes = [];
@@ -101,8 +101,8 @@ export class MidyGM2 {
101
101
  };
102
102
  initSoundFontTable(): any[];
103
103
  addSoundFont(soundFont: any): void;
104
- loadSoundFont(soundFontUrl: any): Promise<void>;
105
- loadMIDI(midiUrl: any): Promise<void>;
104
+ loadSoundFont(input: any): Promise<void>;
105
+ loadMIDI(input: any): Promise<void>;
106
106
  setChannelAudioNodes(audioContext: any): {
107
107
  gainL: any;
108
108
  gainR: any;
@@ -111,7 +111,8 @@ export class MidyGM2 {
111
111
  resetChannelTable(channel: any): void;
112
112
  createChannels(audioContext: any): any[];
113
113
  createNoteBuffer(voiceParams: any, isSF3: any): Promise<any>;
114
- createBufferSource(voiceParams: any, audioBuffer: any): any;
114
+ isLoopDrum(channel: any, noteNumber: any): boolean;
115
+ createBufferSource(channel: any, noteNumber: any, voiceParams: any, audioBuffer: any): any;
115
116
  scheduleTimelineEvents(t: any, resumeTime: any, queueIndex: any): Promise<any>;
116
117
  getQueueIndex(second: any): number;
117
118
  playNotes(): Promise<any>;
@@ -184,13 +185,13 @@ export class MidyGM2 {
184
185
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, noteOffEvent: any): Promise<void>;
185
186
  noteOn(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): Promise<void>;
186
187
  disconnectNote(note: any): void;
187
- stopNote(channel: any, note: any, endTime: any, stopTime: any): Promise<any>;
188
- scheduleNoteOff(channelNumber: any, note: any, _velocity: any, endTime: any, force: any): Promise<any> | undefined;
188
+ releaseNote(channel: any, note: any, endTime: any): Promise<any>;
189
+ scheduleNoteOff(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, force: any): void;
189
190
  findNoteOffTarget(channel: any, noteNumber: any): any;
190
- noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): Promise<any> | undefined;
191
- releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
192
- releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
193
- handleMIDIMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<any>;
191
+ noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): void;
192
+ releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
193
+ releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
194
+ handleMIDIMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<void>;
194
195
  handleProgramChange(channelNumber: any, programNumber: any, _scheduleTime: any): void;
195
196
  handleChannelPressure(channelNumber: any, value: any, scheduleTime: any): void;
196
197
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any, scheduleTime: any): void;
@@ -240,6 +241,7 @@ export class MidyGM2 {
240
241
  setSustainPedal(channelNumber: any, value: any, scheduleTime: any): void;
241
242
  setPortamento(channelNumber: any, value: any, scheduleTime: any): void;
242
243
  setSostenutoPedal(channelNumber: any, value: any, scheduleTime: any): void;
244
+ getSoftPedalFactor(channel: any, note: any): number;
243
245
  setSoftPedal(channelNumber: any, softPedal: any, scheduleTime: any): void;
244
246
  setReverbSendLevel(channelNumber: any, reverbSendLevel: any, scheduleTime: any): void;
245
247
  setChorusSendLevel(channelNumber: any, chorusSendLevel: any, scheduleTime: any): void;
@@ -306,7 +308,7 @@ export class MidyGM2 {
306
308
  resetControlTable(table: any): any;
307
309
  applyControlTable(channel: any, controllerType: any): void;
308
310
  handleControlChangeSysEx(data: any): void;
309
- getKeyBasedInstrumentControlValue(channel: any, keyNumber: any, controllerType: any): number;
311
+ getKeyBasedInstrumentControlValue(channel: any, keyNumber: any, controllerType: any): any;
310
312
  handleKeyBasedInstrumentControlSysEx(data: any, scheduleTime: any): void;
311
313
  handleSysEx(data: any, scheduleTime: any): void;
312
314
  scheduleTask(callback: any, scheduleTime: any): Promise<any>;
@@ -314,7 +316,7 @@ export class MidyGM2 {
314
316
  declare class Note {
315
317
  constructor(noteNumber: any, velocity: any, startTime: any, voice: any, voiceParams: any);
316
318
  index: number;
317
- noteOffEvent: any;
319
+ ending: boolean;
318
320
  bufferSource: any;
319
321
  filterNode: any;
320
322
  filterDepth: any;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}