@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.
@@ -165,12 +165,14 @@ export class MidyGMLite {
165
165
  addSoundFont(soundFont) {
166
166
  const index = this.soundFonts.length;
167
167
  this.soundFonts.push(soundFont);
168
- soundFont.parsed.presetHeaders.forEach((presetHeader) => {
168
+ const presetHeaders = soundFont.parsed.presetHeaders;
169
+ for (let i = 0; i < presetHeaders.length; i++) {
170
+ const presetHeader = presetHeaders[i];
169
171
  if (!presetHeader.presetName.startsWith("\u0000")) { // TODO: Only SF3 generated by PolyPone?
170
172
  const banks = this.soundFontTable[presetHeader.preset];
171
173
  banks.set(presetHeader.bank, index);
172
174
  }
173
- });
175
+ }
174
176
  }
175
177
  async loadSoundFont(soundFontUrl) {
176
178
  const response = await fetch(soundFontUrl);
@@ -215,27 +217,25 @@ export class MidyGMLite {
215
217
  return channels;
216
218
  }
217
219
  async createNoteBuffer(instrumentKey, isSF3) {
220
+ const sampleStart = instrumentKey.start;
218
221
  const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
219
222
  if (isSF3) {
220
- const sample = new Uint8Array(instrumentKey.sample.length);
221
- sample.set(instrumentKey.sample);
223
+ const sample = instrumentKey.sample.slice(sampleStart, sampleEnd);
222
224
  const audioBuffer = await this.audioContext.decodeAudioData(sample.buffer);
223
- for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
224
- const channelData = audioBuffer.getChannelData(channel);
225
- channelData.set(channelData.subarray(0, sampleEnd));
226
- }
227
225
  return audioBuffer;
228
226
  }
229
227
  else {
230
- const sample = instrumentKey.sample.subarray(0, sampleEnd);
231
- const floatSample = this.convertToFloat32Array(sample);
228
+ const sample = instrumentKey.sample.subarray(sampleStart, sampleEnd);
232
229
  const audioBuffer = new AudioBuffer({
233
230
  numberOfChannels: 1,
234
231
  length: sample.length,
235
232
  sampleRate: instrumentKey.sampleRate,
236
233
  });
237
234
  const channelData = audioBuffer.getChannelData(0);
238
- channelData.set(floatSample);
235
+ const int16Array = new Int16Array(sample.buffer);
236
+ for (let i = 0; i < int16Array.length; i++) {
237
+ channelData[i] = int16Array[i] / 32768;
238
+ }
239
239
  return audioBuffer;
240
240
  }
241
241
  }
@@ -251,14 +251,6 @@ export class MidyGMLite {
251
251
  }
252
252
  return bufferSource;
253
253
  }
254
- convertToFloat32Array(uint8Array) {
255
- const int16Array = new Int16Array(uint8Array.buffer);
256
- const float32Array = new Float32Array(int16Array.length);
257
- for (let i = 0; i < int16Array.length; i++) {
258
- float32Array[i] = int16Array[i] / 32768;
259
- }
260
- return float32Array;
261
- }
262
254
  async scheduleTimelineEvents(t, offset, queueIndex) {
263
255
  while (queueIndex < this.timeline.length) {
264
256
  const event = this.timeline[queueIndex];
@@ -369,9 +361,11 @@ export class MidyGMLite {
369
361
  bank: this.channels[i].bank,
370
362
  };
371
363
  }
372
- midi.tracks.forEach((track) => {
364
+ for (let i = 0; i < midi.tracks.length; i++) {
365
+ const track = midi.tracks[i];
373
366
  let currentTicks = 0;
374
- track.forEach((event) => {
367
+ for (let j = 0; j < track.length; j++) {
368
+ const event = track[j];
375
369
  currentTicks += event.deltaTime;
376
370
  event.ticks = currentTicks;
377
371
  switch (event.type) {
@@ -391,8 +385,8 @@ export class MidyGMLite {
391
385
  }
392
386
  delete event.deltaTime;
393
387
  timeline.push(event);
394
- });
395
- });
388
+ }
389
+ }
396
390
  const priority = {
397
391
  controller: 0,
398
392
  sysEx: 1,
@@ -417,7 +411,7 @@ export class MidyGMLite {
417
411
  }
418
412
  return { instruments, timeline };
419
413
  }
420
- async stopChannelNotes(channelNumber, velocity, stopPedal) {
414
+ async stopChannelNotes(channelNumber, velocity, force) {
421
415
  const now = this.audioContext.currentTime;
422
416
  const channel = this.channels[channelNumber];
423
417
  channel.scheduledNotes.forEach((noteList) => {
@@ -425,16 +419,16 @@ export class MidyGMLite {
425
419
  const note = noteList[i];
426
420
  if (!note)
427
421
  continue;
428
- const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
422
+ const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, force);
429
423
  this.notePromises.push(promise);
430
424
  }
431
425
  });
432
426
  channel.scheduledNotes.clear();
433
427
  await Promise.all(this.notePromises);
434
428
  }
435
- stopNotes(velocity, stopPedal) {
429
+ stopNotes(velocity, force) {
436
430
  for (let i = 0; i < this.channels.length; i++) {
437
- this.stopChannelNotes(i, velocity, stopPedal);
431
+ this.stopChannelNotes(i, velocity, force);
438
432
  }
439
433
  return Promise.all(this.notePromises);
440
434
  }
@@ -610,7 +604,7 @@ export class MidyGMLite {
610
604
  note.volumeNode = new GainNode(this.audioContext);
611
605
  note.filterNode = new BiquadFilterNode(this.audioContext, {
612
606
  type: "lowpass",
613
- Q: instrumentKey.initialFilterQ / 10 * channel.filterResonance, // dB
607
+ Q: instrumentKey.initialFilterQ / 10, // dB
614
608
  });
615
609
  this.setVolumeEnvelope(note);
616
610
  this.setFilterEnvelope(note);
@@ -623,7 +617,7 @@ export class MidyGMLite {
623
617
  }
624
618
  note.bufferSource.connect(note.filterNode);
625
619
  note.filterNode.connect(note.volumeNode);
626
- note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
620
+ note.bufferSource.start(startTime);
627
621
  return note;
628
622
  }
629
623
  async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
@@ -652,9 +646,38 @@ export class MidyGMLite {
652
646
  const now = this.audioContext.currentTime;
653
647
  return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
654
648
  }
655
- scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, stopPedal = false) {
649
+ stopNote(stopTime, endTime, scheduledNotes, index) {
650
+ const note = scheduledNotes[index];
651
+ note.volumeNode.gain
652
+ .cancelScheduledValues(stopTime)
653
+ .linearRampToValueAtTime(0, endTime);
654
+ note.ending = true;
655
+ this.scheduleTask(() => {
656
+ note.bufferSource.loop = false;
657
+ }, endTime);
658
+ return new Promise((resolve) => {
659
+ note.bufferSource.onended = () => {
660
+ scheduledNotes[index] = null;
661
+ note.bufferSource.disconnect();
662
+ note.volumeNode.disconnect();
663
+ note.filterNode.disconnect();
664
+ if (note.modulationDepth) {
665
+ note.volumeDepth.disconnect();
666
+ note.modulationDepth.disconnect();
667
+ note.modulationLFO.stop();
668
+ }
669
+ if (note.vibratoDepth) {
670
+ note.vibratoDepth.disconnect();
671
+ note.vibratoLFO.stop();
672
+ }
673
+ resolve();
674
+ };
675
+ note.bufferSource.stop(endTime);
676
+ });
677
+ }
678
+ scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, force) {
656
679
  const channel = this.channels[channelNumber];
657
- if (stopPedal && channel.sustainPedal)
680
+ if (!force && channel.sustainPedal)
658
681
  return;
659
682
  if (!channel.scheduledNotes.has(noteNumber))
660
683
  return;
@@ -666,32 +689,11 @@ export class MidyGMLite {
666
689
  if (note.ending)
667
690
  continue;
668
691
  const volEndTime = stopTime + note.instrumentKey.volRelease;
669
- note.volumeNode.gain
670
- .cancelScheduledValues(stopTime)
671
- .linearRampToValueAtTime(0, volEndTime);
672
692
  const modRelease = stopTime + note.instrumentKey.modRelease;
673
693
  note.filterNode.frequency
674
694
  .cancelScheduledValues(stopTime)
675
695
  .linearRampToValueAtTime(0, modRelease);
676
- note.ending = true;
677
- this.scheduleTask(() => {
678
- note.bufferSource.loop = false;
679
- }, stopTime);
680
- return new Promise((resolve) => {
681
- note.bufferSource.onended = () => {
682
- scheduledNotes[i] = null;
683
- note.bufferSource.disconnect();
684
- note.volumeNode.disconnect();
685
- note.filterNode.disconnect();
686
- if (note.modulationDepth) {
687
- note.volumeDepth.disconnect();
688
- note.modulationDepth.disconnect();
689
- note.modulationLFO.stop();
690
- }
691
- resolve();
692
- };
693
- note.bufferSource.stop(volEndTime);
694
- });
696
+ this.stopNote(stopTime, volEndTime, scheduledNotes, i);
695
697
  }
696
698
  }
697
699
  releaseNote(channelNumber, noteNumber, velocity) {
@@ -800,7 +802,7 @@ export class MidyGMLite {
800
802
  setVolume(channelNumber, volume) {
801
803
  const channel = this.channels[channelNumber];
802
804
  channel.volume = volume / 127;
803
- this.updateChannelGain(channel);
805
+ this.updateChannelVolume(channel);
804
806
  }
805
807
  panToGain(pan) {
806
808
  const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
@@ -812,18 +814,18 @@ export class MidyGMLite {
812
814
  setPan(channelNumber, pan) {
813
815
  const channel = this.channels[channelNumber];
814
816
  channel.pan = pan;
815
- this.updateChannelGain(channel);
817
+ this.updateChannelVolume(channel);
816
818
  }
817
819
  setExpression(channelNumber, expression) {
818
820
  const channel = this.channels[channelNumber];
819
821
  channel.expression = expression / 127;
820
- this.updateChannelGain(channel);
822
+ this.updateChannelVolume(channel);
821
823
  }
822
824
  dataEntryLSB(channelNumber, value) {
823
825
  this.channels[channelNumber].dataLSB = value;
824
826
  this.handleRPN(channelNumber);
825
827
  }
826
- updateChannelGain(channel) {
828
+ updateChannelVolume(channel) {
827
829
  const now = this.audioContext.currentTime;
828
830
  const volume = channel.volume * channel.expression;
829
831
  const { gainLeft, gainRight } = this.panToGain(channel.pan);
@@ -918,11 +920,12 @@ export class MidyGMLite {
918
920
  }
919
921
  }
920
922
  GM1SystemOn() {
921
- this.channels.forEach((channel) => {
923
+ for (let i = 0; i < this.channels.length; i++) {
924
+ const channel = this.channels[i];
922
925
  channel.bankMSB = 0;
923
926
  channel.bankLSB = 0;
924
927
  channel.bank = 0;
925
- });
928
+ }
926
929
  this.channels[9].bankMSB = 1;
927
930
  this.channels[9].bank = 128;
928
931
  }
package/esm/midy.d.ts CHANGED
@@ -159,7 +159,7 @@ export class Midy {
159
159
  createChannels(audioContext: any): any[];
160
160
  createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
161
161
  createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
162
- convertToFloat32Array(uint8Array: any): Float32Array;
162
+ findPortamentoTarget(queueIndex: any): any;
163
163
  scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
164
164
  getQueueIndex(second: any): number;
165
165
  playNotes(): Promise<any>;
@@ -169,8 +169,8 @@ export class Midy {
169
169
  instruments: Set<any>;
170
170
  timeline: any[];
171
171
  };
172
- stopChannelNotes(channelNumber: any, velocity: any, stopPedal: any): Promise<void>;
173
- stopNotes(velocity: any, stopPedal: any): Promise<any[]>;
172
+ stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
173
+ stopNotes(velocity: any, force: any): Promise<any[]>;
174
174
  start(): Promise<void>;
175
175
  stop(): void;
176
176
  pause(): void;
@@ -206,18 +206,21 @@ export class Midy {
206
206
  centToHz(cent: any): number;
207
207
  calcSemitoneOffset(channel: any): any;
208
208
  calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
209
+ setPortamentoStartVolumeEnvelope(channel: any, note: any): void;
209
210
  setVolumeEnvelope(channel: any, note: any): void;
210
211
  setPitch(note: any, semitoneOffset: any): void;
211
212
  clampCutoffFrequency(frequency: any): number;
213
+ setPortamentoStartFilterEnvelope(channel: any, note: any): void;
212
214
  setFilterEnvelope(channel: any, note: any): void;
213
215
  startModulation(channel: any, note: any, startTime: any): void;
214
216
  startVibrato(channel: any, note: any, startTime: any): void;
215
- createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
217
+ createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, portamento: any, isSF3: any): Promise<Note>;
216
218
  calcBank(channel: any, channelNumber: any): any;
217
- scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
218
- noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
219
- scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
220
- releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
219
+ scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
220
+ noteOn(channelNumber: any, noteNumber: any, velocity: any, portamento: any): Promise<void>;
221
+ stopNote(stopTime: any, endTime: any, scheduledNotes: any, index: any): Promise<any>;
222
+ scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
223
+ releaseNote(channelNumber: any, noteNumber: any, velocity: any, portamentoNoteNumber: any): Promise<any> | undefined;
221
224
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
222
225
  releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
223
226
  handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
@@ -276,7 +279,7 @@ export class Midy {
276
279
  setExpression(channelNumber: any, expression: any): void;
277
280
  setBankLSB(channelNumber: any, lsb: any): void;
278
281
  dataEntryLSB(channelNumber: any, value: any): void;
279
- updateChannelGain(channel: any): void;
282
+ updateChannelVolume(channel: any): void;
280
283
  setSustainPedal(channelNumber: any, value: any): void;
281
284
  setPortamento(channelNumber: any, value: any): void;
282
285
  setReverbSendLevel(channelNumber: any, reverbSendLevel: any): void;
package/esm/midy.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAwBA;IAkCE;;;;;;;;;;;;;;;;;;;;;;;;;MAyBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAgCF;;;;;OAYC;IA5HD,qBAAmB;IACnB,kBAAc;IACd,yBAAqB;IACrB,2BAAuB;IACvB;;;MAGE;IACF;;;;;;MAME;IACF,cAAa;IACb,cAAa;IACb,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;IAmDlB;;;;;MA4BE;IAGA,kBAAgC;IAChC;;;;;MAAqD;IACrD,gBAA4C;IAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IACjD;;;MAA8D;IAC9D;;;;;;;;MAAyD;IAO3D,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAiBC;IAED,+DAuBC;IAED,mEAWC;IAED,2CAcC;IAED,2EA8DC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAoGC;IAED,+EAoBC;IAED,qDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,kFAuBC;IAED;;;;MAWC;IAED,gFAUC;IAED,mFAYC;IAED,sGAcC;IAID;;;MA+BC;IAED;;;;;;;;MA0CC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,mFAGC;IAED,gEAUC;IAED,iDAeC;IAED,+CAwBC;IAED,6CAIC;IAED,gEAoBC;IAED,iDAyBC;IAED,+DA0BC;IAED,4DAiBC;IAED,yIA6CC;IAED,gDAQC;IAED,mHAwCC;IAED,2FASC;IAED,qFA4BC;IAED,yJAqCC;IAED,qHAUC;IAED,kEAeC;IAED,oEAYC;IAED,gFAqBC;IAED,sFAcC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,uDAOC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAqCC;IAED,2EASC;IAED,+CAEC;IAED,qCAkBC;IAED,8DAIC;IAED,iEAIC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,+CAEC;IAED,mDAGC;IAED,wCAUC;IAED,sDAMC;IAED,oDAEC;IAED,mEAqBC;IAED,mEAqBC;IAED,wDAWC;IAED,uDAGC;IAED,mEAaC;IAED,2DAGC;IAED,yDAYC;IAED,yDAUC;IAED,uDAUC;IAED,2DAWC;IAED,6DAGC;IAED,6DAGC;IAED,kFAeC;IAED,2DAMC;IAED,gDAyBC;IAGD,wCAEC;IAGD,wCAEC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAaC;IAED,kDAKC;IAED,iEAOC;IAED,8CAKC;IAED,yDAMC;IAED,gDAKC;IAED,6DAMC;IAED,wDAKC;IAED,6EAKC;IAED,+CAEC;IAED,8CAEC;IAED,+CAEC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBASC;IAED,oBASC;IAED,yDAiDC;IAED,yCAGC;IAED,mCAQC;IAED,6CAGC;IAED,2CAMC;IAED,+CAGC;IAED,+CAMC;IAED,mDAeC;IAED,4CAOC;IAED,+BAKC;IAED,qDAiBC;IAED,gCAMC;IAED,kCAEC;IA6BD,4CAEC;IAED,4CAaC;IAED,+BAiBC;IAED,wFAKC;IAED,mCAQC;IAED,qCAEC;IAED,oCAUC;IAED,sCAEC;IAED,oCAaC;IAED,sCAEC;IAED,wCAWC;IAED,0CAEC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAnhED;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"}