@marmooo/midy 0.2.0 → 0.2.2
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/LICENSE +201 -0
- package/README.md +118 -0
- package/esm/midy-GM1.d.ts +12 -10
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +85 -78
- package/esm/midy-GM2.d.ts +40 -22
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +377 -194
- package/esm/midy-GMLite.d.ts +9 -7
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +64 -61
- package/esm/midy.d.ts +39 -21
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +444 -252
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +12 -10
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +85 -78
- package/script/midy-GM2.d.ts +40 -22
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +377 -194
- package/script/midy-GMLite.d.ts +9 -7
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +64 -61
- package/script/midy.d.ts +39 -21
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +444 -252
package/package.json
CHANGED
package/script/midy-GM1.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export class MidyGM1 {
|
|
2
2
|
static channelSettings: {
|
|
3
3
|
currentBufferSource: null;
|
|
4
|
+
detune: number;
|
|
4
5
|
program: number;
|
|
5
6
|
bank: number;
|
|
6
7
|
dataMSB: number;
|
|
@@ -92,11 +93,13 @@ export class MidyGM1 {
|
|
|
92
93
|
getActiveNotes(channel: any, time: any): Map<any, any>;
|
|
93
94
|
getActiveNote(noteList: any, time: any): any;
|
|
94
95
|
cbToRatio(cb: any): number;
|
|
96
|
+
rateToCent(rate: any): number;
|
|
97
|
+
centToRate(cent: any): number;
|
|
95
98
|
centToHz(cent: any): number;
|
|
96
|
-
|
|
99
|
+
calcChannelDetune(channel: any): any;
|
|
100
|
+
updateDetune(channel: any): void;
|
|
97
101
|
setVolumeEnvelope(note: any): void;
|
|
98
|
-
|
|
99
|
-
setPitch(channel: any, note: any): void;
|
|
102
|
+
setPitchEnvelope(note: any): void;
|
|
100
103
|
clampCutoffFrequency(frequency: any): number;
|
|
101
104
|
setFilterEnvelope(note: any): void;
|
|
102
105
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
@@ -112,9 +115,9 @@ export class MidyGM1 {
|
|
|
112
115
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
113
116
|
setPitchBend(channelNumber: any, value: any): void;
|
|
114
117
|
setModLfoToPitch(channel: any, note: any): void;
|
|
115
|
-
setModLfoToVolume(note: any): void;
|
|
116
118
|
setVibLfoToPitch(channel: any, note: any): void;
|
|
117
119
|
setModLfoToFilterFc(note: any): void;
|
|
120
|
+
setModLfoToVolume(note: any): void;
|
|
118
121
|
setDelayModLFO(note: any): void;
|
|
119
122
|
setFreqModLFO(note: any): void;
|
|
120
123
|
createVoiceParamsHandlers(): {
|
|
@@ -129,7 +132,7 @@ export class MidyGM1 {
|
|
|
129
132
|
delayVibLFO: (channel: any, note: any, prevValue: any) => void;
|
|
130
133
|
freqVibLFO: (channel: any, note: any, _prevValue: any) => void;
|
|
131
134
|
};
|
|
132
|
-
getControllerState(channel: any, noteNumber: any, velocity: any): Float32Array
|
|
135
|
+
getControllerState(channel: any, noteNumber: any, velocity: any): Float32Array<any>;
|
|
133
136
|
applyVoiceParams(channel: any, controllerType: any): void;
|
|
134
137
|
createControlChangeHandlers(): {
|
|
135
138
|
1: (channelNumber: any, modulation: any) => void;
|
|
@@ -164,13 +167,12 @@ export class MidyGM1 {
|
|
|
164
167
|
setRPNMSB(channelNumber: any, value: any): void;
|
|
165
168
|
setRPNLSB(channelNumber: any, value: any): void;
|
|
166
169
|
dataEntryMSB(channelNumber: any, value: any): void;
|
|
167
|
-
updateDetune(channel: any, detune: any): void;
|
|
168
170
|
handlePitchBendRangeRPN(channelNumber: any): void;
|
|
169
|
-
setPitchBendRange(channelNumber: any,
|
|
171
|
+
setPitchBendRange(channelNumber: any, value: any): void;
|
|
170
172
|
handleFineTuningRPN(channelNumber: any): void;
|
|
171
|
-
setFineTuning(channelNumber: any,
|
|
173
|
+
setFineTuning(channelNumber: any, value: any): void;
|
|
172
174
|
handleCoarseTuningRPN(channelNumber: any): void;
|
|
173
|
-
setCoarseTuning(channelNumber: any,
|
|
175
|
+
setCoarseTuning(channelNumber: any, value: any): void;
|
|
174
176
|
allSoundOff(channelNumber: any): Promise<void>;
|
|
175
177
|
resetAllControllers(channelNumber: any): void;
|
|
176
178
|
allNotesOff(channelNumber: any): Promise<void>;
|
|
@@ -187,7 +189,7 @@ declare class Note {
|
|
|
187
189
|
constructor(noteNumber: any, velocity: any, startTime: any, voice: any, voiceParams: any);
|
|
188
190
|
bufferSource: any;
|
|
189
191
|
filterNode: any;
|
|
190
|
-
|
|
192
|
+
volumeEnvelopeNode: any;
|
|
191
193
|
volumeDepth: any;
|
|
192
194
|
modulationLFO: any;
|
|
193
195
|
modulationDepth: any;
|
package/script/midy-GM1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqFA;IAoBE
|
|
1
|
+
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqFA;IAoBE;;;;;;;;;;;;MAYE;IAEF,+BAQC;IAzCD,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;IAClB,iCAA8B;IAiB5B,kBAAgC;IAChC,gBAA4C;IAC5C;;;;;;;;;;;MAA2D;IAC3D;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,6DA2BC;IAED,iEAUC;IAED,2EA+CC;IAED,mCAOC;IAED,0BAkDC;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,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,iCAWC;IAED,mCAgBC;IAED,kCAqBC;IAED,6CAIC;IAED,mCAuBC;IAED,+DAoBC;IAED,gHA2BC;IAED,kGAgDC;IAED,0EAGC;IAED,qFA4BC;IAED,6HAuBC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,mDASC;IAED,gDASC;IAED,gDASC;IAED,qCAMC;IAED,mCAQC;IAED,gCAOC;IAED,+BAMC;IAED;;;;;;;;;;;MA2CC;IAED,oFAMC;IAED,0DA6CC;IAED;;;;;;;;;;;;;MAeC;IAED,+EASC;IAED,qCAiBC;IAED,8DAKC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,wCAWC;IAED,sDAKC;IAED,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,kDAKC;IAED,wDASC;IAED,8CAKC;IAED,oDAOC;IAED,gDAKC;IAED,sDAOC;IAED,+CAEC;IAED,8CAqBC;IAED,+CAEC;IAED,4DAgBC;IAED,oBAMC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAjzCD;IAUE,0FAMC;IAfD,kBAAa;IACb,gBAAW;IACX,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAChB,gBAAW;IACX,kBAAa;IAGX,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
|
package/script/midy-GM1.js
CHANGED
|
@@ -17,7 +17,7 @@ class Note {
|
|
|
17
17
|
writable: true,
|
|
18
18
|
value: void 0
|
|
19
19
|
});
|
|
20
|
-
Object.defineProperty(this, "
|
|
20
|
+
Object.defineProperty(this, "volumeEnvelopeNode", {
|
|
21
21
|
enumerable: true,
|
|
22
22
|
configurable: true,
|
|
23
23
|
writable: true,
|
|
@@ -596,16 +596,35 @@ class MidyGM1 {
|
|
|
596
596
|
cbToRatio(cb) {
|
|
597
597
|
return Math.pow(10, cb / 200);
|
|
598
598
|
}
|
|
599
|
+
rateToCent(rate) {
|
|
600
|
+
return 1200 * Math.log2(rate);
|
|
601
|
+
}
|
|
602
|
+
centToRate(cent) {
|
|
603
|
+
return Math.pow(2, cent / 1200);
|
|
604
|
+
}
|
|
599
605
|
centToHz(cent) {
|
|
600
|
-
return 8.176 *
|
|
606
|
+
return 8.176 * this.centToRate(cent);
|
|
601
607
|
}
|
|
602
|
-
|
|
608
|
+
calcChannelDetune(channel) {
|
|
603
609
|
const tuning = channel.coarseTuning + channel.fineTuning;
|
|
604
610
|
const pitchWheel = channel.state.pitchWheel * 2 - 1;
|
|
605
|
-
const pitchWheelSensitivity = channel.state.pitchWheelSensitivity *
|
|
611
|
+
const pitchWheelSensitivity = channel.state.pitchWheelSensitivity * 12800;
|
|
606
612
|
const pitch = pitchWheel * pitchWheelSensitivity;
|
|
607
613
|
return tuning + pitch;
|
|
608
614
|
}
|
|
615
|
+
updateDetune(channel) {
|
|
616
|
+
const now = this.audioContext.currentTime;
|
|
617
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
618
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
619
|
+
const note = noteList[i];
|
|
620
|
+
if (!note)
|
|
621
|
+
continue;
|
|
622
|
+
note.bufferSource.detune
|
|
623
|
+
.cancelScheduledValues(now)
|
|
624
|
+
.setValueAtTime(channel.detune, now);
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
}
|
|
609
628
|
setVolumeEnvelope(note) {
|
|
610
629
|
const now = this.audioContext.currentTime;
|
|
611
630
|
const { voiceParams, startTime } = note;
|
|
@@ -615,7 +634,7 @@ class MidyGM1 {
|
|
|
615
634
|
const volAttack = volDelay + voiceParams.volAttack;
|
|
616
635
|
const volHold = volAttack + voiceParams.volHold;
|
|
617
636
|
const volDecay = volHold + voiceParams.volDecay;
|
|
618
|
-
note.
|
|
637
|
+
note.volumeEnvelopeNode.gain
|
|
619
638
|
.cancelScheduledValues(now)
|
|
620
639
|
.setValueAtTime(0, startTime)
|
|
621
640
|
.setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
|
|
@@ -623,32 +642,28 @@ class MidyGM1 {
|
|
|
623
642
|
.setValueAtTime(attackVolume, volHold)
|
|
624
643
|
.linearRampToValueAtTime(sustainVolume, volDecay);
|
|
625
644
|
}
|
|
626
|
-
|
|
645
|
+
setPitchEnvelope(note) {
|
|
627
646
|
const now = this.audioContext.currentTime;
|
|
647
|
+
const { voiceParams } = note;
|
|
648
|
+
const baseRate = voiceParams.playbackRate;
|
|
628
649
|
note.bufferSource.playbackRate
|
|
629
650
|
.cancelScheduledValues(now)
|
|
630
|
-
.setValueAtTime(
|
|
631
|
-
|
|
632
|
-
setPitch(channel, note) {
|
|
633
|
-
const now = this.audioContext.currentTime;
|
|
634
|
-
const { startTime } = note;
|
|
635
|
-
const basePitch = this.calcSemitoneOffset(channel) * 100;
|
|
636
|
-
note.bufferSource.detune
|
|
637
|
-
.cancelScheduledValues(now)
|
|
638
|
-
.setValueAtTime(basePitch, startTime);
|
|
639
|
-
const modEnvToPitch = note.voiceParams.modEnvToPitch;
|
|
651
|
+
.setValueAtTime(baseRate, now);
|
|
652
|
+
const modEnvToPitch = voiceParams.modEnvToPitch;
|
|
640
653
|
if (modEnvToPitch === 0)
|
|
641
654
|
return;
|
|
655
|
+
const basePitch = this.rateToCent(baseRate);
|
|
642
656
|
const peekPitch = basePitch + modEnvToPitch;
|
|
657
|
+
const peekRate = this.centToRate(peekPitch);
|
|
643
658
|
const modDelay = startTime + voiceParams.modDelay;
|
|
644
659
|
const modAttack = modDelay + voiceParams.modAttack;
|
|
645
660
|
const modHold = modAttack + voiceParams.modHold;
|
|
646
661
|
const modDecay = modHold + voiceParams.modDecay;
|
|
647
|
-
note.bufferSource.
|
|
648
|
-
.setValueAtTime(
|
|
649
|
-
.exponentialRampToValueAtTime(
|
|
650
|
-
.setValueAtTime(
|
|
651
|
-
.linearRampToValueAtTime(
|
|
662
|
+
note.bufferSource.playbackRate
|
|
663
|
+
.setValueAtTime(baseRate, modDelay)
|
|
664
|
+
.exponentialRampToValueAtTime(peekRate, modAttack)
|
|
665
|
+
.setValueAtTime(peekRate, modHold)
|
|
666
|
+
.linearRampToValueAtTime(baseRate, modDecay);
|
|
652
667
|
}
|
|
653
668
|
clampCutoffFrequency(frequency) {
|
|
654
669
|
const minFrequency = 20; // min Hz of initialFilterFc
|
|
@@ -695,27 +710,26 @@ class MidyGM1 {
|
|
|
695
710
|
note.modulationLFO.connect(note.modulationDepth);
|
|
696
711
|
note.modulationDepth.connect(note.bufferSource.detune);
|
|
697
712
|
note.modulationLFO.connect(note.volumeDepth);
|
|
698
|
-
note.volumeDepth.connect(note.
|
|
713
|
+
note.volumeDepth.connect(note.volumeEnvelopeNode.gain);
|
|
699
714
|
}
|
|
700
715
|
async createNote(channel, voice, noteNumber, velocity, startTime, isSF3) {
|
|
701
716
|
const state = channel.state;
|
|
702
717
|
const voiceParams = voice.getAllParams(state.array);
|
|
703
718
|
const note = new Note(noteNumber, velocity, startTime, voice, voiceParams);
|
|
704
719
|
note.bufferSource = await this.createNoteBufferNode(voiceParams, isSF3);
|
|
705
|
-
note.
|
|
720
|
+
note.volumeEnvelopeNode = new GainNode(this.audioContext);
|
|
706
721
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
707
722
|
type: "lowpass",
|
|
708
723
|
Q: voiceParams.initialFilterQ / 10, // dB
|
|
709
724
|
});
|
|
710
725
|
this.setVolumeEnvelope(note);
|
|
711
726
|
this.setFilterEnvelope(note);
|
|
712
|
-
this.
|
|
727
|
+
this.setPitchEnvelope(note);
|
|
713
728
|
if (0 < state.modulationDepth) {
|
|
714
|
-
this.setPitch(channel, note);
|
|
715
729
|
this.startModulation(channel, note, startTime);
|
|
716
730
|
}
|
|
717
731
|
note.bufferSource.connect(note.filterNode);
|
|
718
|
-
note.filterNode.connect(note.
|
|
732
|
+
note.filterNode.connect(note.volumeEnvelopeNode);
|
|
719
733
|
note.bufferSource.start(startTime);
|
|
720
734
|
return note;
|
|
721
735
|
}
|
|
@@ -731,8 +745,8 @@ class MidyGM1 {
|
|
|
731
745
|
if (!voice)
|
|
732
746
|
return;
|
|
733
747
|
const note = await this.createNote(channel, voice, noteNumber, velocity, startTime, isSF3);
|
|
734
|
-
note.
|
|
735
|
-
note.
|
|
748
|
+
note.volumeEnvelopeNode.connect(channel.gainL);
|
|
749
|
+
note.volumeEnvelopeNode.connect(channel.gainR);
|
|
736
750
|
const exclusiveClass = note.voiceParams.exclusiveClass;
|
|
737
751
|
if (exclusiveClass !== 0) {
|
|
738
752
|
if (this.exclusiveClassMap.has(exclusiveClass)) {
|
|
@@ -760,7 +774,7 @@ class MidyGM1 {
|
|
|
760
774
|
}
|
|
761
775
|
stopNote(endTime, stopTime, scheduledNotes, index) {
|
|
762
776
|
const note = scheduledNotes[index];
|
|
763
|
-
note.
|
|
777
|
+
note.volumeEnvelopeNode.gain
|
|
764
778
|
.cancelScheduledValues(endTime)
|
|
765
779
|
.linearRampToValueAtTime(0, stopTime);
|
|
766
780
|
note.ending = true;
|
|
@@ -771,8 +785,8 @@ class MidyGM1 {
|
|
|
771
785
|
note.bufferSource.onended = () => {
|
|
772
786
|
scheduledNotes[index] = null;
|
|
773
787
|
note.bufferSource.disconnect();
|
|
774
|
-
note.volumeNode.disconnect();
|
|
775
788
|
note.filterNode.disconnect();
|
|
789
|
+
note.volumeEnvelopeNode.disconnect();
|
|
776
790
|
if (note.modulationDepth) {
|
|
777
791
|
note.volumeDepth.disconnect();
|
|
778
792
|
note.modulationDepth.disconnect();
|
|
@@ -859,29 +873,22 @@ class MidyGM1 {
|
|
|
859
873
|
setPitchBend(channelNumber, value) {
|
|
860
874
|
const channel = this.channels[channelNumber];
|
|
861
875
|
const state = channel.state;
|
|
876
|
+
const prev = state.pitchWheel * 2 - 1;
|
|
877
|
+
const next = (value - 8192) / 8192;
|
|
862
878
|
state.pitchWheel = value / 16383;
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
this.
|
|
879
|
+
channel.detune += (next - prev) * state.pitchWheelSensitivity * 12800;
|
|
880
|
+
this.updateDetune(channel);
|
|
881
|
+
this.applyVoiceParams(channel, 14);
|
|
866
882
|
}
|
|
867
883
|
setModLfoToPitch(channel, note) {
|
|
868
884
|
const now = this.audioContext.currentTime;
|
|
869
885
|
const modLfoToPitch = note.voiceParams.modLfoToPitch;
|
|
870
|
-
const
|
|
886
|
+
const baseDepth = Math.abs(modLfoToPitch) +
|
|
871
887
|
channel.state.modulationDepth;
|
|
872
|
-
const
|
|
888
|
+
const modulationDepth = baseDepth * Math.sign(modLfoToPitch);
|
|
873
889
|
note.modulationDepth.gain
|
|
874
890
|
.cancelScheduledValues(now)
|
|
875
|
-
.setValueAtTime(modulationDepth
|
|
876
|
-
}
|
|
877
|
-
setModLfoToVolume(note) {
|
|
878
|
-
const now = this.audioContext.currentTime;
|
|
879
|
-
const modLfoToVolume = note.voiceParams.modLfoToVolume;
|
|
880
|
-
const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
|
|
881
|
-
const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
|
|
882
|
-
note.volumeDepth.gain
|
|
883
|
-
.cancelScheduledValues(now)
|
|
884
|
-
.setValueAtTime(volumeDepth * volumeDepthSign, now);
|
|
891
|
+
.setValueAtTime(modulationDepth, now);
|
|
885
892
|
}
|
|
886
893
|
setVibLfoToPitch(channel, note) {
|
|
887
894
|
const now = this.audioContext.currentTime;
|
|
@@ -900,6 +907,15 @@ class MidyGM1 {
|
|
|
900
907
|
.cancelScheduledValues(now)
|
|
901
908
|
.setValueAtTime(modLfoToFilterFc, now);
|
|
902
909
|
}
|
|
910
|
+
setModLfoToVolume(note) {
|
|
911
|
+
const now = this.audioContext.currentTime;
|
|
912
|
+
const modLfoToVolume = note.voiceParams.modLfoToVolume;
|
|
913
|
+
const baseDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
|
|
914
|
+
const volumeDepth = baseDepth * Math.sign(modLfoToVolume);
|
|
915
|
+
note.volumeDepth.gain
|
|
916
|
+
.cancelScheduledValues(now)
|
|
917
|
+
.setValueAtTime(volumeDepth, now);
|
|
918
|
+
}
|
|
903
919
|
setDelayModLFO(note) {
|
|
904
920
|
const now = this.audioContext.currentTime;
|
|
905
921
|
const startTime = note.startTime;
|
|
@@ -999,7 +1015,7 @@ class MidyGM1 {
|
|
|
999
1015
|
noteVoiceParams[key] = voiceParams[key];
|
|
1000
1016
|
}
|
|
1001
1017
|
this.setFilterEnvelope(channel, note);
|
|
1002
|
-
this.
|
|
1018
|
+
this.setPitchEnvelope(note);
|
|
1003
1019
|
}
|
|
1004
1020
|
else if (volumeEnvelopeKeySet.has(key)) {
|
|
1005
1021
|
if (appliedVolumeEnvelope)
|
|
@@ -1053,7 +1069,7 @@ class MidyGM1 {
|
|
|
1053
1069
|
note.modulationDepth.gain.setValueAtTime(channel.state.modulationDepth, now);
|
|
1054
1070
|
}
|
|
1055
1071
|
else {
|
|
1056
|
-
this.
|
|
1072
|
+
this.setPitchEnvelope(note);
|
|
1057
1073
|
this.startModulation(channel, note, now);
|
|
1058
1074
|
}
|
|
1059
1075
|
}
|
|
@@ -1162,59 +1178,49 @@ class MidyGM1 {
|
|
|
1162
1178
|
this.channels[channelNumber].dataMSB = value;
|
|
1163
1179
|
this.handleRPN(channelNumber);
|
|
1164
1180
|
}
|
|
1165
|
-
updateDetune(channel, detune) {
|
|
1166
|
-
const now = this.audioContext.currentTime;
|
|
1167
|
-
channel.scheduledNotes.forEach((noteList) => {
|
|
1168
|
-
for (let i = 0; i < noteList.length; i++) {
|
|
1169
|
-
const note = noteList[i];
|
|
1170
|
-
if (!note)
|
|
1171
|
-
continue;
|
|
1172
|
-
const { bufferSource } = note;
|
|
1173
|
-
bufferSource.detune
|
|
1174
|
-
.cancelScheduledValues(now)
|
|
1175
|
-
.setValueAtTime(detune, now);
|
|
1176
|
-
}
|
|
1177
|
-
});
|
|
1178
|
-
}
|
|
1179
1181
|
handlePitchBendRangeRPN(channelNumber) {
|
|
1180
1182
|
const channel = this.channels[channelNumber];
|
|
1181
1183
|
this.limitData(channel, 0, 127, 0, 99);
|
|
1182
1184
|
const pitchBendRange = channel.dataMSB + channel.dataLSB / 100;
|
|
1183
1185
|
this.setPitchBendRange(channelNumber, pitchBendRange);
|
|
1184
1186
|
}
|
|
1185
|
-
setPitchBendRange(channelNumber,
|
|
1187
|
+
setPitchBendRange(channelNumber, value) {
|
|
1186
1188
|
const channel = this.channels[channelNumber];
|
|
1187
1189
|
const state = channel.state;
|
|
1188
|
-
|
|
1189
|
-
const
|
|
1190
|
-
|
|
1190
|
+
const prev = state.pitchWheelSensitivity;
|
|
1191
|
+
const next = value / 128;
|
|
1192
|
+
state.pitchWheelSensitivity = next;
|
|
1193
|
+
channel.detune += (state.pitchWheel * 2 - 1) * (next - prev) * 12800;
|
|
1194
|
+
this.updateDetune(channel);
|
|
1191
1195
|
this.applyVoiceParams(channel, 16);
|
|
1192
1196
|
}
|
|
1193
1197
|
handleFineTuningRPN(channelNumber) {
|
|
1194
1198
|
const channel = this.channels[channelNumber];
|
|
1195
1199
|
this.limitData(channel, 0, 127, 0, 127);
|
|
1196
|
-
const fineTuning =
|
|
1200
|
+
const fineTuning = channel.dataMSB * 128 + channel.dataLSB;
|
|
1197
1201
|
this.setFineTuning(channelNumber, fineTuning);
|
|
1198
1202
|
}
|
|
1199
|
-
setFineTuning(channelNumber,
|
|
1203
|
+
setFineTuning(channelNumber, value) {
|
|
1200
1204
|
const channel = this.channels[channelNumber];
|
|
1201
|
-
const
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
+
const prev = channel.fineTuning;
|
|
1206
|
+
const next = (value - 8192) / 8.192; // cent
|
|
1207
|
+
channel.fineTuning = next;
|
|
1208
|
+
channel.detune += next - prev;
|
|
1209
|
+
this.updateDetune(channel);
|
|
1205
1210
|
}
|
|
1206
1211
|
handleCoarseTuningRPN(channelNumber) {
|
|
1207
1212
|
const channel = this.channels[channelNumber];
|
|
1208
1213
|
this.limitDataMSB(channel, 0, 127);
|
|
1209
|
-
const coarseTuning = channel.dataMSB
|
|
1210
|
-
this.
|
|
1214
|
+
const coarseTuning = channel.dataMSB;
|
|
1215
|
+
this.setCoarseTuning(channelNumber, coarseTuning);
|
|
1211
1216
|
}
|
|
1212
|
-
setCoarseTuning(channelNumber,
|
|
1217
|
+
setCoarseTuning(channelNumber, value) {
|
|
1213
1218
|
const channel = this.channels[channelNumber];
|
|
1214
|
-
const
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1219
|
+
const prev = channel.coarseTuning;
|
|
1220
|
+
const next = (value - 64) * 100; // cent
|
|
1221
|
+
channel.coarseTuning = next;
|
|
1222
|
+
channel.detune += next - prev;
|
|
1223
|
+
this.updateDetune(channel);
|
|
1218
1224
|
}
|
|
1219
1225
|
allSoundOff(channelNumber) {
|
|
1220
1226
|
return this.stopChannelNotes(channelNumber, 0, true);
|
|
@@ -1328,6 +1334,7 @@ Object.defineProperty(MidyGM1, "channelSettings", {
|
|
|
1328
1334
|
writable: true,
|
|
1329
1335
|
value: {
|
|
1330
1336
|
currentBufferSource: null,
|
|
1337
|
+
detune: 0,
|
|
1331
1338
|
program: 0,
|
|
1332
1339
|
bank: 0,
|
|
1333
1340
|
dataMSB: 0,
|
package/script/midy-GM2.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export class MidyGM2 {
|
|
2
2
|
static channelSettings: {
|
|
3
3
|
currentBufferSource: null;
|
|
4
|
+
detune: number;
|
|
5
|
+
scaleOctaveTuningTable: any[];
|
|
6
|
+
pressureTable: Uint8Array<ArrayBuffer>;
|
|
7
|
+
keyBasedInstrumentControlTable: Int8Array<ArrayBuffer>;
|
|
4
8
|
program: number;
|
|
5
9
|
bank: number;
|
|
6
10
|
bankMSB: number;
|
|
@@ -79,8 +83,8 @@ export class MidyGM2 {
|
|
|
79
83
|
vibLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
|
|
80
84
|
modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
|
|
81
85
|
modLfoToVolume: (channel: any, note: any) => void;
|
|
82
|
-
chorusEffectsSend: (
|
|
83
|
-
reverbEffectsSend: (
|
|
86
|
+
chorusEffectsSend: (channel: any, note: any, prevValue: any) => void;
|
|
87
|
+
reverbEffectsSend: (channel: any, note: any, prevValue: any) => void;
|
|
84
88
|
delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
|
|
85
89
|
freqModLFO: (_channel: any, note: any, _prevValue: any) => void;
|
|
86
90
|
delayVibLFO: (channel: any, note: any, prevValue: any) => void;
|
|
@@ -182,12 +186,16 @@ export class MidyGM2 {
|
|
|
182
186
|
feedbackGains: any[];
|
|
183
187
|
};
|
|
184
188
|
cbToRatio(cb: any): number;
|
|
189
|
+
rateToCent(rate: any): number;
|
|
190
|
+
centToRate(cent: any): number;
|
|
185
191
|
centToHz(cent: any): number;
|
|
186
|
-
|
|
192
|
+
calcChannelDetune(channel: any): any;
|
|
193
|
+
calcNoteDetune(channel: any, note: any): any;
|
|
194
|
+
updateDetune(channel: any): void;
|
|
195
|
+
getPortamentoTime(channel: any): number;
|
|
187
196
|
setPortamentoStartVolumeEnvelope(channel: any, note: any): void;
|
|
188
|
-
setVolumeEnvelope(note: any): void;
|
|
189
|
-
|
|
190
|
-
setPitch(channel: any, note: any): void;
|
|
197
|
+
setVolumeEnvelope(channel: any, note: any): void;
|
|
198
|
+
setPitchEnvelope(note: any): void;
|
|
191
199
|
clampCutoffFrequency(frequency: any): number;
|
|
192
200
|
setPortamentoStartFilterEnvelope(channel: any, note: any): void;
|
|
193
201
|
setFilterEnvelope(channel: any, note: any): void;
|
|
@@ -204,15 +212,16 @@ export class MidyGM2 {
|
|
|
204
212
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
205
213
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
206
214
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
207
|
-
handleChannelPressure(channelNumber: any,
|
|
215
|
+
handleChannelPressure(channelNumber: any, value: any): void;
|
|
216
|
+
setChannelPressure(channel: any, note: any): void;
|
|
208
217
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
209
218
|
setPitchBend(channelNumber: any, value: any): void;
|
|
210
219
|
setModLfoToPitch(channel: any, note: any): void;
|
|
211
|
-
setModLfoToVolume(note: any): void;
|
|
212
|
-
setChorusEffectsSend(note: any, prevValue: any): void;
|
|
213
|
-
setReverbEffectsSend(note: any, prevValue: any): void;
|
|
214
220
|
setVibLfoToPitch(channel: any, note: any): void;
|
|
215
|
-
setModLfoToFilterFc(note: any): void;
|
|
221
|
+
setModLfoToFilterFc(channel: any, note: any): void;
|
|
222
|
+
setModLfoToVolume(channel: any, note: any): void;
|
|
223
|
+
setReverbEffectsSend(channel: any, note: any, prevValue: any): void;
|
|
224
|
+
setChorusEffectsSend(channel: any, note: any, prevValue: any): void;
|
|
216
225
|
setDelayModLFO(note: any): void;
|
|
217
226
|
setFreqModLFO(note: any): void;
|
|
218
227
|
createVoiceParamsHandlers(): {
|
|
@@ -220,14 +229,14 @@ export class MidyGM2 {
|
|
|
220
229
|
vibLfoToPitch: (channel: any, note: any, _prevValue: any) => void;
|
|
221
230
|
modLfoToFilterFc: (channel: any, note: any, _prevValue: any) => void;
|
|
222
231
|
modLfoToVolume: (channel: any, note: any) => void;
|
|
223
|
-
chorusEffectsSend: (
|
|
224
|
-
reverbEffectsSend: (
|
|
232
|
+
chorusEffectsSend: (channel: any, note: any, prevValue: any) => void;
|
|
233
|
+
reverbEffectsSend: (channel: any, note: any, prevValue: any) => void;
|
|
225
234
|
delayModLFO: (_channel: any, note: any, _prevValue: any) => void;
|
|
226
235
|
freqModLFO: (_channel: any, note: any, _prevValue: any) => void;
|
|
227
236
|
delayVibLFO: (channel: any, note: any, prevValue: any) => void;
|
|
228
237
|
freqVibLFO: (channel: any, note: any, _prevValue: any) => void;
|
|
229
238
|
};
|
|
230
|
-
getControllerState(channel: any, noteNumber: any, velocity: any): Float32Array
|
|
239
|
+
getControllerState(channel: any, noteNumber: any, velocity: any): Float32Array<any>;
|
|
231
240
|
applyVoiceParams(channel: any, controllerType: any): void;
|
|
232
241
|
createControlChangeHandlers(): {
|
|
233
242
|
0: (channelNumber: any, msb: any) => void;
|
|
@@ -260,11 +269,13 @@ export class MidyGM2 {
|
|
|
260
269
|
updateModulation(channel: any): void;
|
|
261
270
|
setModulationDepth(channelNumber: any, modulation: any): void;
|
|
262
271
|
setPortamentoTime(channelNumber: any, portamentoTime: any): void;
|
|
272
|
+
setKeyBasedVolume(channel: any): void;
|
|
263
273
|
setVolume(channelNumber: any, volume: any): void;
|
|
264
274
|
panToGain(pan: any): {
|
|
265
275
|
gainLeft: number;
|
|
266
276
|
gainRight: number;
|
|
267
277
|
};
|
|
278
|
+
setKeyBasedPan(channel: any): void;
|
|
268
279
|
setPan(channelNumber: any, pan: any): void;
|
|
269
280
|
setExpression(channelNumber: any, expression: any): void;
|
|
270
281
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
@@ -272,23 +283,22 @@ export class MidyGM2 {
|
|
|
272
283
|
updateChannelVolume(channel: any): void;
|
|
273
284
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
274
285
|
setPortamento(channelNumber: any, value: any): void;
|
|
275
|
-
setReverbSendLevel(channelNumber: any, reverbSendLevel: any): void;
|
|
276
|
-
setChorusSendLevel(channelNumber: any, chorusSendLevel: any): void;
|
|
277
286
|
setSostenutoPedal(channelNumber: any, value: any): void;
|
|
278
287
|
setSoftPedal(channelNumber: any, softPedal: any): void;
|
|
288
|
+
setReverbSendLevel(channelNumber: any, reverbSendLevel: any): void;
|
|
289
|
+
setChorusSendLevel(channelNumber: any, chorusSendLevel: any): void;
|
|
279
290
|
limitData(channel: any, minMSB: any, maxMSB: any, minLSB: any, maxLSB: any): void;
|
|
280
291
|
limitDataMSB(channel: any, minMSB: any, maxMSB: any): void;
|
|
281
292
|
handleRPN(channelNumber: any): void;
|
|
282
293
|
setRPNMSB(channelNumber: any, value: any): void;
|
|
283
294
|
setRPNLSB(channelNumber: any, value: any): void;
|
|
284
295
|
dataEntryMSB(channelNumber: any, value: any): void;
|
|
285
|
-
updateDetune(channel: any, detune: any): void;
|
|
286
296
|
handlePitchBendRangeRPN(channelNumber: any): void;
|
|
287
|
-
setPitchBendRange(channelNumber: any,
|
|
297
|
+
setPitchBendRange(channelNumber: any, value: any): void;
|
|
288
298
|
handleFineTuningRPN(channelNumber: any): void;
|
|
289
|
-
setFineTuning(channelNumber: any,
|
|
299
|
+
setFineTuning(channelNumber: any, value: any): void;
|
|
290
300
|
handleCoarseTuningRPN(channelNumber: any): void;
|
|
291
|
-
setCoarseTuning(channelNumber: any,
|
|
301
|
+
setCoarseTuning(channelNumber: any, value: any): void;
|
|
292
302
|
handleModulationDepthRangeRPN(channelNumber: any): void;
|
|
293
303
|
setModulationDepthRange(channelNumber: any, modulationDepthRange: any): void;
|
|
294
304
|
allSoundOff(channelNumber: any): Promise<void>;
|
|
@@ -305,9 +315,9 @@ export class MidyGM2 {
|
|
|
305
315
|
handleMasterVolumeSysEx(data: any): void;
|
|
306
316
|
setMasterVolume(volume: any): void;
|
|
307
317
|
handleMasterFineTuningSysEx(data: any): void;
|
|
308
|
-
setMasterFineTuning(
|
|
318
|
+
setMasterFineTuning(value: any): void;
|
|
309
319
|
handleMasterCoarseTuningSysEx(data: any): void;
|
|
310
|
-
setMasterCoarseTuning(
|
|
320
|
+
setMasterCoarseTuning(value: any): void;
|
|
311
321
|
handleGlobalParameterControlSysEx(data: any): void;
|
|
312
322
|
handleReverbParameterSysEx(data: any): void;
|
|
313
323
|
setReverbType(type: any): void;
|
|
@@ -326,6 +336,11 @@ export class MidyGM2 {
|
|
|
326
336
|
getChorusFeedback(value: any): number;
|
|
327
337
|
setChorusSendToReverb(value: any): void;
|
|
328
338
|
getChorusSendToReverb(value: any): number;
|
|
339
|
+
getChannelBitmap(data: any): any[];
|
|
340
|
+
handleScaleOctaveTuning1ByteFormatSysEx(data: any): void;
|
|
341
|
+
handleChannelPressureSysEx(data: any): void;
|
|
342
|
+
getKeyBasedInstrumentControlValue(channel: any, keyNumber: any, controllerType: any): number;
|
|
343
|
+
handleKeyBasedInstrumentControlSysEx(data: any): void;
|
|
329
344
|
handleExclusiveMessage(data: any): void;
|
|
330
345
|
handleSysEx(data: any): void;
|
|
331
346
|
scheduleTask(callback: any, startTime: any): Promise<any>;
|
|
@@ -334,7 +349,10 @@ declare class Note {
|
|
|
334
349
|
constructor(noteNumber: any, velocity: any, startTime: any, voice: any, voiceParams: any);
|
|
335
350
|
bufferSource: any;
|
|
336
351
|
filterNode: any;
|
|
352
|
+
volumeEnvelopeNode: any;
|
|
337
353
|
volumeNode: any;
|
|
354
|
+
gainL: any;
|
|
355
|
+
gainR: any;
|
|
338
356
|
volumeDepth: any;
|
|
339
357
|
modulationLFO: any;
|
|
340
358
|
modulationDepth: any;
|
package/script/midy-GM2.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}
|