@marmooo/midy 0.1.3 → 0.1.4
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-GM1.d.ts +3 -2
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +66 -55
- package/esm/midy-GM2.d.ts +3 -2
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +61 -47
- package/esm/midy-GMLite.d.ts +3 -2
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +64 -53
- package/esm/midy.d.ts +14 -3
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +140 -53
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +3 -2
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +66 -55
- package/script/midy-GM2.d.ts +3 -2
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +61 -47
- package/script/midy-GMLite.d.ts +3 -2
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +64 -53
- package/script/midy.d.ts +14 -3
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +140 -53
package/esm/midy-GM1.d.ts
CHANGED
|
@@ -79,12 +79,13 @@ export class MidyGM1 {
|
|
|
79
79
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
80
80
|
setVolumeEnvelope(note: any): void;
|
|
81
81
|
setPitch(note: any, semitoneOffset: any): void;
|
|
82
|
-
|
|
82
|
+
clampCutoffFrequency(frequency: any): number;
|
|
83
|
+
setFilterEnvelope(note: any): void;
|
|
83
84
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
84
85
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
85
86
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
86
87
|
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
87
|
-
scheduleNoteRelease(channelNumber: any, noteNumber: any,
|
|
88
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
|
|
88
89
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
89
90
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
90
91
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
package/esm/midy-GM1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAwBA;IAmBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA9CD,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,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,
|
|
1
|
+
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAwBA;IAmBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA9CD,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,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,kGA6BC;IAED,0EAGC;IAED,uIAyCC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,2FA+BC;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;AApjCD;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"}
|
package/esm/midy-GM1.js
CHANGED
|
@@ -432,12 +432,13 @@ export class MidyGM1 {
|
|
|
432
432
|
const now = this.audioContext.currentTime;
|
|
433
433
|
const channel = this.channels[channelNumber];
|
|
434
434
|
channel.scheduledNotes.forEach((noteList) => {
|
|
435
|
-
noteList.
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
435
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
436
|
+
const note = noteList[i];
|
|
437
|
+
if (!note)
|
|
438
|
+
continue;
|
|
439
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
|
|
440
|
+
this.notePromises.push(promise);
|
|
441
|
+
}
|
|
441
442
|
});
|
|
442
443
|
channel.scheduledNotes.clear();
|
|
443
444
|
await Promise.all(this.notePromises);
|
|
@@ -529,7 +530,6 @@ export class MidyGM1 {
|
|
|
529
530
|
}
|
|
530
531
|
setVolumeEnvelope(note) {
|
|
531
532
|
const { instrumentKey, startTime } = note;
|
|
532
|
-
note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
|
|
533
533
|
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
|
|
534
534
|
const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
|
|
535
535
|
const volDelay = startTime + instrumentKey.volDelay;
|
|
@@ -537,6 +537,8 @@ export class MidyGM1 {
|
|
|
537
537
|
const volHold = volAttack + instrumentKey.volHold;
|
|
538
538
|
const volDecay = volHold + instrumentKey.volDecay;
|
|
539
539
|
note.volumeNode.gain
|
|
540
|
+
.cancelScheduledValues(startTime)
|
|
541
|
+
.setValueAtTime(0, startTime)
|
|
540
542
|
.setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
|
|
541
543
|
.exponentialRampToValueAtTime(attackVolume, volAttack)
|
|
542
544
|
.setValueAtTime(attackVolume, volHold)
|
|
@@ -560,29 +562,27 @@ export class MidyGM1 {
|
|
|
560
562
|
.setValueAtTime(peekPitch, modHold)
|
|
561
563
|
.linearRampToValueAtTime(basePitch, modDecay);
|
|
562
564
|
}
|
|
563
|
-
|
|
564
|
-
const
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
const
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
const
|
|
575
|
-
const
|
|
565
|
+
clampCutoffFrequency(frequency) {
|
|
566
|
+
const minFrequency = 20; // min Hz of initialFilterFc
|
|
567
|
+
const maxFrequency = 20000; // max Hz of initialFilterFc
|
|
568
|
+
return Math.max(minFrequency, Math.min(frequency, maxFrequency));
|
|
569
|
+
}
|
|
570
|
+
setFilterEnvelope(note) {
|
|
571
|
+
const { instrumentKey, startTime } = note;
|
|
572
|
+
const baseFreq = this.centToHz(instrumentKey.initialFilterFc);
|
|
573
|
+
const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc);
|
|
574
|
+
const sustainFreq = baseFreq +
|
|
575
|
+
(peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
|
|
576
|
+
const adjustedBaseFreq = this.clampCutoffFrequency(baseFreq);
|
|
577
|
+
const adjustedPeekFreq = this.clampCutoffFrequency(peekFreq);
|
|
578
|
+
const adjustedSustainFreq = this.clampCutoffFrequency(sustainFreq);
|
|
576
579
|
const modDelay = startTime + instrumentKey.modDelay;
|
|
577
580
|
const modAttack = modDelay + instrumentKey.modAttack;
|
|
578
581
|
const modHold = modAttack + instrumentKey.modHold;
|
|
579
582
|
const modDecay = modHold + instrumentKey.modDecay;
|
|
580
|
-
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
581
|
-
type: "lowpass",
|
|
582
|
-
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
583
|
-
frequency: adjustedBaseFreq,
|
|
584
|
-
});
|
|
585
583
|
note.filterNode.frequency
|
|
584
|
+
.cancelScheduledValues(startTime)
|
|
585
|
+
.setValueAtTime(adjustedBaseFreq, startTime)
|
|
586
586
|
.setValueAtTime(adjustedBaseFreq, modDelay)
|
|
587
587
|
.exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
|
|
588
588
|
.setValueAtTime(adjustedPeekFreq, modHold)
|
|
@@ -619,8 +619,13 @@ export class MidyGM1 {
|
|
|
619
619
|
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
620
620
|
const note = new Note(noteNumber, velocity, startTime, instrumentKey);
|
|
621
621
|
note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
|
|
622
|
-
this.
|
|
622
|
+
note.volumeNode = new GainNode(this.audioContext);
|
|
623
|
+
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
624
|
+
type: "lowpass",
|
|
625
|
+
Q: instrumentKey.initialFilterQ / 10 * channel.filterResonance, // dB
|
|
626
|
+
});
|
|
623
627
|
this.setVolumeEnvelope(note);
|
|
628
|
+
this.setFilterEnvelope(note);
|
|
624
629
|
if (0 < channel.modulationDepth) {
|
|
625
630
|
this.setPitch(note, semitoneOffset);
|
|
626
631
|
this.startModulation(channel, note, startTime);
|
|
@@ -659,7 +664,7 @@ export class MidyGM1 {
|
|
|
659
664
|
const now = this.audioContext.currentTime;
|
|
660
665
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
661
666
|
}
|
|
662
|
-
scheduleNoteRelease(channelNumber, noteNumber,
|
|
667
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, stopPedal = false) {
|
|
663
668
|
const channel = this.channels[channelNumber];
|
|
664
669
|
if (stopPedal && channel.sustainPedal)
|
|
665
670
|
return;
|
|
@@ -672,14 +677,11 @@ export class MidyGM1 {
|
|
|
672
677
|
continue;
|
|
673
678
|
if (note.ending)
|
|
674
679
|
continue;
|
|
675
|
-
const
|
|
676
|
-
const volEndTime = stopTime +
|
|
677
|
-
note.instrumentKey.volRelease * velocityRate;
|
|
680
|
+
const volEndTime = stopTime + note.instrumentKey.volRelease;
|
|
678
681
|
note.volumeNode.gain
|
|
679
682
|
.cancelScheduledValues(stopTime)
|
|
680
683
|
.linearRampToValueAtTime(0, volEndTime);
|
|
681
|
-
const modRelease = stopTime +
|
|
682
|
-
note.instrumentKey.modRelease * velocityRate;
|
|
684
|
+
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
683
685
|
note.filterNode.frequency
|
|
684
686
|
.cancelScheduledValues(stopTime)
|
|
685
687
|
.linearRampToValueAtTime(0, modRelease);
|
|
@@ -715,13 +717,14 @@ export class MidyGM1 {
|
|
|
715
717
|
const promises = [];
|
|
716
718
|
channel.sustainPedal = false;
|
|
717
719
|
channel.scheduledNotes.forEach((noteList) => {
|
|
718
|
-
noteList.
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
720
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
721
|
+
const note = noteList[i];
|
|
722
|
+
if (!note)
|
|
723
|
+
continue;
|
|
724
|
+
const { noteNumber } = note;
|
|
725
|
+
const promise = this.releaseNote(channelNumber, noteNumber, velocity);
|
|
726
|
+
promises.push(promise);
|
|
727
|
+
}
|
|
725
728
|
});
|
|
726
729
|
return promises;
|
|
727
730
|
}
|
|
@@ -791,15 +794,19 @@ export class MidyGM1 {
|
|
|
791
794
|
}
|
|
792
795
|
updateModulation(channel) {
|
|
793
796
|
const now = this.audioContext.currentTime;
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
797
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
798
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
799
|
+
const note = noteList[i];
|
|
800
|
+
if (!note)
|
|
801
|
+
continue;
|
|
802
|
+
if (note.modulationDepth) {
|
|
803
|
+
note.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
807
|
+
this.setPitch(note, semitoneOffset);
|
|
808
|
+
this.startModulation(channel, note, now);
|
|
809
|
+
}
|
|
803
810
|
}
|
|
804
811
|
});
|
|
805
812
|
}
|
|
@@ -907,13 +914,17 @@ export class MidyGM1 {
|
|
|
907
914
|
}
|
|
908
915
|
updateDetune(channel, detuneChange) {
|
|
909
916
|
const now = this.audioContext.currentTime;
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
.
|
|
917
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
918
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
919
|
+
const note = noteList[i];
|
|
920
|
+
if (!note)
|
|
921
|
+
continue;
|
|
922
|
+
const { bufferSource } = note;
|
|
923
|
+
const detune = bufferSource.detune.value + detuneChange;
|
|
924
|
+
bufferSource.detune
|
|
925
|
+
.cancelScheduledValues(now)
|
|
926
|
+
.setValueAtTime(detune, now);
|
|
927
|
+
}
|
|
917
928
|
});
|
|
918
929
|
}
|
|
919
930
|
handlePitchBendRangeRPN(channelNumber) {
|
package/esm/midy-GM2.d.ts
CHANGED
|
@@ -167,14 +167,15 @@ export class MidyGM2 {
|
|
|
167
167
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
168
168
|
setVolumeEnvelope(note: any): void;
|
|
169
169
|
setPitch(note: any, semitoneOffset: any): void;
|
|
170
|
-
|
|
170
|
+
clampCutoffFrequency(frequency: any): number;
|
|
171
|
+
setFilterEnvelope(channel: any, note: any): void;
|
|
171
172
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
172
173
|
startVibrato(channel: any, note: any, startTime: any): void;
|
|
173
174
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
174
175
|
calcBank(channel: any, channelNumber: any): any;
|
|
175
176
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
176
177
|
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
177
|
-
scheduleNoteRelease(channelNumber: any, noteNumber: any,
|
|
178
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
|
|
178
179
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
179
180
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
180
181
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
package/esm/midy-GM2.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAwBA;IAkCE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAgCF;;;;;OAWC;IAtHD,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;IA8ClB;;;;;MA4BE;IAGA,kBAAgC;IAChC;;;;;MAAqD;IACrD,gBAA4C;IAC5C,gBAAiD;IACjD;;;MAA8D;IAC9D;;;;;;;;MAAyD;IAO3D,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAcC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EAkDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgGC;IAED,mFAmBC;IAED,yDAKC;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,
|
|
1
|
+
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}
|
package/esm/midy-GM2.js
CHANGED
|
@@ -545,12 +545,13 @@ export class MidyGM2 {
|
|
|
545
545
|
const now = this.audioContext.currentTime;
|
|
546
546
|
const channel = this.channels[channelNumber];
|
|
547
547
|
channel.scheduledNotes.forEach((noteList) => {
|
|
548
|
-
noteList.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
548
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
549
|
+
const note = noteList[i];
|
|
550
|
+
if (!note)
|
|
551
|
+
continue;
|
|
552
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
|
|
553
|
+
this.notePromises.push(promise);
|
|
554
|
+
}
|
|
554
555
|
});
|
|
555
556
|
channel.scheduledNotes.clear();
|
|
556
557
|
await Promise.all(this.notePromises);
|
|
@@ -773,7 +774,6 @@ export class MidyGM2 {
|
|
|
773
774
|
}
|
|
774
775
|
setVolumeEnvelope(note) {
|
|
775
776
|
const { instrumentKey, startTime } = note;
|
|
776
|
-
note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
|
|
777
777
|
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
|
|
778
778
|
const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
|
|
779
779
|
const volDelay = startTime + instrumentKey.volDelay;
|
|
@@ -781,6 +781,8 @@ export class MidyGM2 {
|
|
|
781
781
|
const volHold = volAttack + instrumentKey.volHold;
|
|
782
782
|
const volDecay = volHold + instrumentKey.volDecay;
|
|
783
783
|
note.volumeNode.gain
|
|
784
|
+
.cancelScheduledValues(startTime)
|
|
785
|
+
.setValueAtTime(0, startTime)
|
|
784
786
|
.setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
|
|
785
787
|
.exponentialRampToValueAtTime(attackVolume, volAttack)
|
|
786
788
|
.setValueAtTime(attackVolume, volHold)
|
|
@@ -804,29 +806,30 @@ export class MidyGM2 {
|
|
|
804
806
|
.setValueAtTime(peekPitch, modHold)
|
|
805
807
|
.linearRampToValueAtTime(basePitch, modDecay);
|
|
806
808
|
}
|
|
807
|
-
|
|
809
|
+
clampCutoffFrequency(frequency) {
|
|
810
|
+
const minFrequency = 20; // min Hz of initialFilterFc
|
|
811
|
+
const maxFrequency = 20000; // max Hz of initialFilterFc
|
|
812
|
+
return Math.max(minFrequency, Math.min(frequency, maxFrequency));
|
|
813
|
+
}
|
|
814
|
+
setFilterEnvelope(channel, note) {
|
|
808
815
|
const { instrumentKey, noteNumber, startTime } = note;
|
|
809
816
|
const softPedalFactor = 1 -
|
|
810
817
|
(0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
|
|
811
|
-
const maxFreq = this.audioContext.sampleRate / 2;
|
|
812
818
|
const baseFreq = this.centToHz(instrumentKey.initialFilterFc) *
|
|
813
819
|
softPedalFactor;
|
|
814
820
|
const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
|
|
815
821
|
const sustainFreq = baseFreq +
|
|
816
822
|
(peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
|
|
817
|
-
const adjustedBaseFreq =
|
|
818
|
-
const adjustedPeekFreq =
|
|
819
|
-
const adjustedSustainFreq =
|
|
823
|
+
const adjustedBaseFreq = this.clampCutoffFrequency(baseFreq);
|
|
824
|
+
const adjustedPeekFreq = this.clampCutoffFrequency(peekFreq);
|
|
825
|
+
const adjustedSustainFreq = this.clampCutoffFrequency(sustainFreq);
|
|
820
826
|
const modDelay = startTime + instrumentKey.modDelay;
|
|
821
827
|
const modAttack = modDelay + instrumentKey.modAttack;
|
|
822
828
|
const modHold = modAttack + instrumentKey.modHold;
|
|
823
829
|
const modDecay = modHold + instrumentKey.modDecay;
|
|
824
|
-
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
825
|
-
type: "lowpass",
|
|
826
|
-
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
827
|
-
frequency: adjustedBaseFreq,
|
|
828
|
-
});
|
|
829
830
|
note.filterNode.frequency
|
|
831
|
+
.cancelScheduledValues(startTime)
|
|
832
|
+
.setValueAtTime(adjustedBaseFreq, startTime)
|
|
830
833
|
.setValueAtTime(adjustedBaseFreq, modDelay)
|
|
831
834
|
.exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
|
|
832
835
|
.setValueAtTime(adjustedPeekFreq, modHold)
|
|
@@ -879,8 +882,13 @@ export class MidyGM2 {
|
|
|
879
882
|
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
880
883
|
const note = new Note(noteNumber, velocity, startTime, instrumentKey);
|
|
881
884
|
note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
|
|
882
|
-
this.
|
|
885
|
+
note.volumeNode = new GainNode(this.audioContext);
|
|
886
|
+
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
887
|
+
type: "lowpass",
|
|
888
|
+
Q: instrumentKey.initialFilterQ / 10 * channel.filterResonance, // dB
|
|
889
|
+
});
|
|
883
890
|
this.setVolumeEnvelope(note);
|
|
891
|
+
this.setFilterEnvelope(channel, note);
|
|
884
892
|
if (0 < channel.vibratoDepth) {
|
|
885
893
|
this.startVibrato(channel, note, startTime);
|
|
886
894
|
}
|
|
@@ -938,7 +946,7 @@ export class MidyGM2 {
|
|
|
938
946
|
const now = this.audioContext.currentTime;
|
|
939
947
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
940
948
|
}
|
|
941
|
-
scheduleNoteRelease(channelNumber, noteNumber,
|
|
949
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, stopPedal = false) {
|
|
942
950
|
const channel = this.channels[channelNumber];
|
|
943
951
|
if (stopPedal && channel.sustainPedal)
|
|
944
952
|
return;
|
|
@@ -953,14 +961,11 @@ export class MidyGM2 {
|
|
|
953
961
|
continue;
|
|
954
962
|
if (note.ending)
|
|
955
963
|
continue;
|
|
956
|
-
const
|
|
957
|
-
const volEndTime = stopTime +
|
|
958
|
-
note.instrumentKey.volRelease * velocityRate;
|
|
964
|
+
const volEndTime = stopTime + note.instrumentKey.volRelease;
|
|
959
965
|
note.volumeNode.gain
|
|
960
966
|
.cancelScheduledValues(stopTime)
|
|
961
967
|
.linearRampToValueAtTime(0, volEndTime);
|
|
962
|
-
const modRelease = stopTime +
|
|
963
|
-
note.instrumentKey.modRelease * velocityRate;
|
|
968
|
+
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
964
969
|
note.filterNode.frequency
|
|
965
970
|
.cancelScheduledValues(stopTime)
|
|
966
971
|
.linearRampToValueAtTime(0, modRelease);
|
|
@@ -1000,13 +1005,14 @@ export class MidyGM2 {
|
|
|
1000
1005
|
const promises = [];
|
|
1001
1006
|
channel.sustainPedal = false;
|
|
1002
1007
|
channel.scheduledNotes.forEach((noteList) => {
|
|
1003
|
-
noteList.
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1008
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1009
|
+
const note = noteList[i];
|
|
1010
|
+
if (!note)
|
|
1011
|
+
continue;
|
|
1012
|
+
const { noteNumber } = note;
|
|
1013
|
+
const promise = this.releaseNote(channelNumber, noteNumber, velocity);
|
|
1014
|
+
promises.push(promise);
|
|
1015
|
+
}
|
|
1010
1016
|
});
|
|
1011
1017
|
return promises;
|
|
1012
1018
|
}
|
|
@@ -1134,15 +1140,19 @@ export class MidyGM2 {
|
|
|
1134
1140
|
}
|
|
1135
1141
|
updateModulation(channel) {
|
|
1136
1142
|
const now = this.audioContext.currentTime;
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1143
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1144
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1145
|
+
const note = noteList[i];
|
|
1146
|
+
if (!note)
|
|
1147
|
+
continue;
|
|
1148
|
+
if (note.modulationDepth) {
|
|
1149
|
+
note.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
|
|
1150
|
+
}
|
|
1151
|
+
else {
|
|
1152
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
1153
|
+
this.setPitch(note, semitoneOffset);
|
|
1154
|
+
this.startModulation(channel, note, now);
|
|
1155
|
+
}
|
|
1146
1156
|
}
|
|
1147
1157
|
});
|
|
1148
1158
|
}
|
|
@@ -1306,13 +1316,17 @@ export class MidyGM2 {
|
|
|
1306
1316
|
}
|
|
1307
1317
|
updateDetune(channel, detuneChange) {
|
|
1308
1318
|
const now = this.audioContext.currentTime;
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
.
|
|
1319
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1320
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1321
|
+
const note = noteList[i];
|
|
1322
|
+
if (!note)
|
|
1323
|
+
continue;
|
|
1324
|
+
const { bufferSource } = note;
|
|
1325
|
+
const detune = bufferSource.detune.value + detuneChange;
|
|
1326
|
+
bufferSource.detune
|
|
1327
|
+
.cancelScheduledValues(now)
|
|
1328
|
+
.setValueAtTime(detune, now);
|
|
1329
|
+
}
|
|
1316
1330
|
});
|
|
1317
1331
|
}
|
|
1318
1332
|
handlePitchBendRangeRPN(channelNumber) {
|
package/esm/midy-GMLite.d.ts
CHANGED
|
@@ -77,12 +77,13 @@ export class MidyGMLite {
|
|
|
77
77
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
78
78
|
setVolumeEnvelope(note: any): void;
|
|
79
79
|
setPitch(note: any, semitoneOffset: any): void;
|
|
80
|
-
|
|
80
|
+
clampCutoffFrequency(frequency: any): number;
|
|
81
|
+
setFilterEnvelope(note: any): void;
|
|
81
82
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
82
83
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
83
84
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
84
85
|
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
85
|
-
scheduleNoteRelease(channelNumber: any, noteNumber: any,
|
|
86
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
|
|
86
87
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
87
88
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
88
89
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
package/esm/midy-GMLite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA5CD,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,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,
|
|
1
|
+
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA5CD,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,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,kGA6BC;IAED,0EAGC;IAED,uIAyCC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,2FA+BC;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;AAl/BD;IAQE,gFAKC;IAZD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|