@marmooo/midy 0.0.3 → 0.0.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 +4 -3
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +41 -38
- package/esm/midy-GM2.d.ts +14 -100
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +79 -40
- package/esm/midy-GMLite.d.ts +4 -3
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +40 -37
- package/esm/midy.d.ts +45 -3
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +96 -34
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +4 -3
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +41 -38
- package/script/midy-GM2.d.ts +14 -100
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +79 -40
- package/script/midy-GMLite.d.ts +4 -3
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +40 -37
- package/script/midy.d.ts +45 -3
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +96 -34
package/script/midy-GM2.d.ts
CHANGED
|
@@ -32,6 +32,14 @@ export class MidyGM2 {
|
|
|
32
32
|
channelPressure: number;
|
|
33
33
|
pitchBendRange: number;
|
|
34
34
|
};
|
|
35
|
+
static controllerDestinationSettings: {
|
|
36
|
+
pitchControl: number;
|
|
37
|
+
filterCutoffControl: number;
|
|
38
|
+
amplitudeControl: number;
|
|
39
|
+
lfoPitchDepth: number;
|
|
40
|
+
lfoFilterDepth: number;
|
|
41
|
+
lfoAmplitudeDepth: number;
|
|
42
|
+
};
|
|
35
43
|
constructor(audioContext: any);
|
|
36
44
|
ticksPerBeat: number;
|
|
37
45
|
totalTime: number;
|
|
@@ -57,55 +65,7 @@ export class MidyGM2 {
|
|
|
57
65
|
notePromises: any[];
|
|
58
66
|
audioContext: any;
|
|
59
67
|
masterGain: any;
|
|
60
|
-
channels:
|
|
61
|
-
scheduledNotes: Map<any, any>;
|
|
62
|
-
sostenutoNotes: Map<any, any>;
|
|
63
|
-
gainNode: any;
|
|
64
|
-
pannerNode: any;
|
|
65
|
-
modulationEffect: {
|
|
66
|
-
lfo: any;
|
|
67
|
-
};
|
|
68
|
-
reverbEffect: {
|
|
69
|
-
convolverNode: any;
|
|
70
|
-
dryGain: any;
|
|
71
|
-
wetGain: any;
|
|
72
|
-
};
|
|
73
|
-
chorusEffect: {
|
|
74
|
-
lfo: any;
|
|
75
|
-
lfoGain: any;
|
|
76
|
-
delayNodes: any[];
|
|
77
|
-
chorusGains: any[];
|
|
78
|
-
};
|
|
79
|
-
expression: number;
|
|
80
|
-
modulation: number;
|
|
81
|
-
sustainPedal: boolean;
|
|
82
|
-
portamento: boolean;
|
|
83
|
-
sostenutoPedal: boolean;
|
|
84
|
-
softPedal: number;
|
|
85
|
-
rpnMSB: number;
|
|
86
|
-
rpnLSB: number;
|
|
87
|
-
channelPressure: number;
|
|
88
|
-
pitchBendRange: number;
|
|
89
|
-
currentBufferSource: null;
|
|
90
|
-
volume: number;
|
|
91
|
-
pan: number;
|
|
92
|
-
portamentoTime: number;
|
|
93
|
-
reverb: number;
|
|
94
|
-
chorus: number;
|
|
95
|
-
vibratoRate: number;
|
|
96
|
-
vibratoDepth: number;
|
|
97
|
-
vibratoDelay: number;
|
|
98
|
-
bank: number;
|
|
99
|
-
bankMSB: number;
|
|
100
|
-
bankLSB: number;
|
|
101
|
-
dataMSB: number;
|
|
102
|
-
dataLSB: number;
|
|
103
|
-
program: number;
|
|
104
|
-
pitchBend: number;
|
|
105
|
-
fineTuning: number;
|
|
106
|
-
coarseTuning: number;
|
|
107
|
-
modulationDepthRange: number;
|
|
108
|
-
}[];
|
|
68
|
+
channels: any[];
|
|
109
69
|
initSoundFontTable(): any[];
|
|
110
70
|
addSoundFont(soundFont: any): void;
|
|
111
71
|
loadSoundFont(soundFontUrl: any): Promise<void>;
|
|
@@ -128,55 +88,7 @@ export class MidyGM2 {
|
|
|
128
88
|
chorusGains: any[];
|
|
129
89
|
};
|
|
130
90
|
};
|
|
131
|
-
createChannels(audioContext: any):
|
|
132
|
-
scheduledNotes: Map<any, any>;
|
|
133
|
-
sostenutoNotes: Map<any, any>;
|
|
134
|
-
gainNode: any;
|
|
135
|
-
pannerNode: any;
|
|
136
|
-
modulationEffect: {
|
|
137
|
-
lfo: any;
|
|
138
|
-
};
|
|
139
|
-
reverbEffect: {
|
|
140
|
-
convolverNode: any;
|
|
141
|
-
dryGain: any;
|
|
142
|
-
wetGain: any;
|
|
143
|
-
};
|
|
144
|
-
chorusEffect: {
|
|
145
|
-
lfo: any;
|
|
146
|
-
lfoGain: any;
|
|
147
|
-
delayNodes: any[];
|
|
148
|
-
chorusGains: any[];
|
|
149
|
-
};
|
|
150
|
-
expression: number;
|
|
151
|
-
modulation: number;
|
|
152
|
-
sustainPedal: boolean;
|
|
153
|
-
portamento: boolean;
|
|
154
|
-
sostenutoPedal: boolean;
|
|
155
|
-
softPedal: number;
|
|
156
|
-
rpnMSB: number;
|
|
157
|
-
rpnLSB: number;
|
|
158
|
-
channelPressure: number;
|
|
159
|
-
pitchBendRange: number;
|
|
160
|
-
currentBufferSource: null;
|
|
161
|
-
volume: number;
|
|
162
|
-
pan: number;
|
|
163
|
-
portamentoTime: number;
|
|
164
|
-
reverb: number;
|
|
165
|
-
chorus: number;
|
|
166
|
-
vibratoRate: number;
|
|
167
|
-
vibratoDepth: number;
|
|
168
|
-
vibratoDelay: number;
|
|
169
|
-
bank: number;
|
|
170
|
-
bankMSB: number;
|
|
171
|
-
bankLSB: number;
|
|
172
|
-
dataMSB: number;
|
|
173
|
-
dataLSB: number;
|
|
174
|
-
program: number;
|
|
175
|
-
pitchBend: number;
|
|
176
|
-
fineTuning: number;
|
|
177
|
-
coarseTuning: number;
|
|
178
|
-
modulationDepthRange: number;
|
|
179
|
-
}[];
|
|
91
|
+
createChannels(audioContext: any): any[];
|
|
180
92
|
createNoteBuffer(noteInfo: any, isSF3: any): Promise<any>;
|
|
181
93
|
createNoteBufferNode(noteInfo: any, isSF3: any): Promise<any>;
|
|
182
94
|
convertToFloat32Array(uint8Array: any): Float32Array;
|
|
@@ -216,6 +128,8 @@ export class MidyGM2 {
|
|
|
216
128
|
connectNoteEffects(channel: any, gainNode: any): void;
|
|
217
129
|
cbToRatio(cb: any): number;
|
|
218
130
|
centToHz(cent: any): number;
|
|
131
|
+
calcSemitoneOffset(channel: any): any;
|
|
132
|
+
calcPlaybackRate(noteInfo: any, noteNumber: any, semitoneOffset: any): number;
|
|
219
133
|
createNoteAudioChain(channel: any, noteInfo: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<{
|
|
220
134
|
bufferSource: any;
|
|
221
135
|
gainNode: any;
|
|
@@ -230,10 +144,10 @@ export class MidyGM2 {
|
|
|
230
144
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
231
145
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
232
146
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
|
|
233
|
-
handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
|
|
234
147
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
235
148
|
handleChannelPressure(channelNumber: any, pressure: any): void;
|
|
236
|
-
|
|
149
|
+
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
150
|
+
handlePitchBend(channelNumber: any, pitchBend: any): void;
|
|
237
151
|
handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
|
|
238
152
|
setBankMSB(channelNumber: any, msb: any): void;
|
|
239
153
|
setModulation(channelNumber: any, modulation: any): void;
|
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":"AAMA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF,+BAMC;
|
|
1
|
+
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAMA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,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;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C,gBAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;;;;MAuBC;IAED,yCAcC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EAkDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA2GC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED;;;;MAoCC;IAED;;;;;MA2CC;IAED,sDA2BC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,8EAEC;IAED;;;;;OAqFC;IAED,gDAQC;IAED,kGAgDC;IAED,0EAGC;IAED,sIA6CC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,wFAmBC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,0DAiBC;IAED,mFAuDC;IAED,+CAEC;IAED,yDAIC;IAED,iEAEC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,+CAEC;IAED,sCAKC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAUC;IAED,uDAGC;IAED,gDAEC;IAED,gDAEC;IAED,+DAuBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,sCAQC;IAED,6CAGC;IAED,8CAMC;IAED,+CAGC;IAED,kDAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
|
package/script/midy-GM2.js
CHANGED
|
@@ -204,11 +204,14 @@ class MidyGM2 {
|
|
|
204
204
|
createChannels(audioContext) {
|
|
205
205
|
const channels = Array.from({ length: 16 }, () => {
|
|
206
206
|
return {
|
|
207
|
-
...
|
|
208
|
-
...
|
|
207
|
+
...Midy.channelSettings,
|
|
208
|
+
...Midy.effectSettings,
|
|
209
209
|
...this.setChannelAudioNodes(audioContext),
|
|
210
210
|
scheduledNotes: new Map(),
|
|
211
211
|
sostenutoNotes: new Map(),
|
|
212
|
+
channelPressure: {
|
|
213
|
+
...Midy.controllerDestinationSettings,
|
|
214
|
+
},
|
|
212
215
|
};
|
|
213
216
|
});
|
|
214
217
|
return channels;
|
|
@@ -263,9 +266,6 @@ class MidyGM2 {
|
|
|
263
266
|
if (event.startTime > t + this.lookAhead)
|
|
264
267
|
break;
|
|
265
268
|
switch (event.type) {
|
|
266
|
-
case "controller":
|
|
267
|
-
this.handleControlChange(this.omni ? 0 : event.channel, event.controllerType, event.value);
|
|
268
|
-
break;
|
|
269
269
|
case "noteOn":
|
|
270
270
|
if (event.velocity !== 0) {
|
|
271
271
|
await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
|
|
@@ -279,9 +279,18 @@ class MidyGM2 {
|
|
|
279
279
|
}
|
|
280
280
|
break;
|
|
281
281
|
}
|
|
282
|
+
case "controller":
|
|
283
|
+
this.handleControlChange(this.omni ? 0 : event.channel, event.controllerType, event.value);
|
|
284
|
+
break;
|
|
282
285
|
case "programChange":
|
|
283
286
|
this.handleProgramChange(event.channel, event.programNumber);
|
|
284
287
|
break;
|
|
288
|
+
case "channelAftertouch":
|
|
289
|
+
this.handleChannelPressure(event.channel, event.amount);
|
|
290
|
+
break;
|
|
291
|
+
case "pitchBend":
|
|
292
|
+
this.handlePitchBend(event.channel, event.value);
|
|
293
|
+
break;
|
|
285
294
|
case "sysEx":
|
|
286
295
|
this.handleSysEx(event.data);
|
|
287
296
|
}
|
|
@@ -645,15 +654,19 @@ class MidyGM2 {
|
|
|
645
654
|
centToHz(cent) {
|
|
646
655
|
return 8.176 * Math.pow(2, cent / 1200);
|
|
647
656
|
}
|
|
648
|
-
|
|
657
|
+
calcSemitoneOffset(channel) {
|
|
649
658
|
const masterTuning = this.masterCoarseTuning + this.masterFineTuning;
|
|
650
659
|
const channelTuning = channel.coarseTuning + channel.fineTuning;
|
|
651
660
|
const tuning = masterTuning + channelTuning;
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
661
|
+
return channel.pitchBend * channel.pitchBendRange + tuning;
|
|
662
|
+
}
|
|
663
|
+
calcPlaybackRate(noteInfo, noteNumber, semitoneOffset) {
|
|
664
|
+
return noteInfo.playbackRate(noteNumber) * Math.pow(2, semitoneOffset / 12);
|
|
665
|
+
}
|
|
666
|
+
async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
|
|
655
667
|
const bufferSource = await this.createNoteBufferNode(noteInfo, isSF3);
|
|
656
|
-
|
|
668
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
669
|
+
bufferSource.playbackRate.value = this.calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
|
|
657
670
|
// volume envelope
|
|
658
671
|
const gainNode = new GainNode(this.audioContext, {
|
|
659
672
|
gain: 0,
|
|
@@ -858,8 +871,6 @@ class MidyGM2 {
|
|
|
858
871
|
return this.releaseNote(channelNumber, data1, data2);
|
|
859
872
|
case 0x90:
|
|
860
873
|
return this.noteOn(channelNumber, data1, data2);
|
|
861
|
-
case 0xA0:
|
|
862
|
-
return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
|
|
863
874
|
case 0xB0:
|
|
864
875
|
return this.handleControlChange(channelNumber, data1, data2);
|
|
865
876
|
case 0xC0:
|
|
@@ -867,38 +878,48 @@ class MidyGM2 {
|
|
|
867
878
|
case 0xD0:
|
|
868
879
|
return this.handleChannelPressure(channelNumber, data1);
|
|
869
880
|
case 0xE0:
|
|
870
|
-
return this.
|
|
881
|
+
return this.handlePitchBendMessage(channelNumber, data1, data2);
|
|
871
882
|
default:
|
|
872
883
|
console.warn(`Unsupported MIDI message: ${messageType.toString(16)}`);
|
|
873
884
|
}
|
|
874
885
|
}
|
|
875
|
-
handlePolyphonicKeyPressure(channelNumber, noteNumber, pressure) {
|
|
876
|
-
const now = this.audioContext.currentTime;
|
|
877
|
-
const channel = this.channels[channelNumber];
|
|
878
|
-
const scheduledNotes = channel.scheduledNotes.get(noteNumber);
|
|
879
|
-
pressure /= 127;
|
|
880
|
-
if (scheduledNotes) {
|
|
881
|
-
scheduledNotes.forEach((scheduledNote) => {
|
|
882
|
-
if (scheduledNote) {
|
|
883
|
-
const { initialAttenuation } = scheduledNote.noteInfo;
|
|
884
|
-
const gain = this.cbToRatio(-initialAttenuation) * pressure;
|
|
885
|
-
scheduledNote.gainNode.gain.cancelScheduledValues(now);
|
|
886
|
-
scheduledNote.gainNode.gain.setValueAtTime(gain, now);
|
|
887
|
-
}
|
|
888
|
-
});
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
886
|
handleProgramChange(channelNumber, program) {
|
|
892
887
|
const channel = this.channels[channelNumber];
|
|
893
888
|
channel.bank = channel.bankMSB * 128 + channel.bankLSB;
|
|
894
889
|
channel.program = program;
|
|
895
890
|
}
|
|
896
891
|
handleChannelPressure(channelNumber, pressure) {
|
|
897
|
-
this.
|
|
892
|
+
const now = this.audioContext.currentTime;
|
|
893
|
+
const channel = this.channels[channelNumber];
|
|
894
|
+
pressure /= 64;
|
|
895
|
+
channel.channelPressure = pressure;
|
|
896
|
+
const activeNotes = this.getActiveNotes(channel);
|
|
897
|
+
if (channel.channelPressure.amplitudeControl !== 1) {
|
|
898
|
+
activeNotes.forEach((activeNote) => {
|
|
899
|
+
const gain = activeNote.gainNode.gain.value;
|
|
900
|
+
activeNote.gainNode.gain
|
|
901
|
+
.cancelScheduledValues(now)
|
|
902
|
+
.setValueAtTime(gain * pressure, now);
|
|
903
|
+
});
|
|
904
|
+
}
|
|
898
905
|
}
|
|
899
|
-
|
|
900
|
-
const pitchBend =
|
|
901
|
-
this.
|
|
906
|
+
handlePitchBendMessage(channelNumber, lsb, msb) {
|
|
907
|
+
const pitchBend = msb * 128 + lsb;
|
|
908
|
+
this.handlePitchBend(channelNumber, pitchBend);
|
|
909
|
+
}
|
|
910
|
+
handlePitchBend(channelNumber, pitchBend) {
|
|
911
|
+
const now = this.audioContext.currentTime;
|
|
912
|
+
const channel = this.channels[channelNumber];
|
|
913
|
+
channel.pitchBend = (pitchBend - 8192) / 8192;
|
|
914
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
915
|
+
const activeNotes = this.getActiveNotes(channel);
|
|
916
|
+
activeNotes.forEach((activeNote) => {
|
|
917
|
+
const { bufferSource, noteInfo, noteNumber } = activeNote;
|
|
918
|
+
const playbackRate = calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
|
|
919
|
+
bufferSource.playbackRate
|
|
920
|
+
.cancelScheduledValues(now)
|
|
921
|
+
.setValueAtTime(playbackRate * pressure, now);
|
|
922
|
+
});
|
|
902
923
|
}
|
|
903
924
|
handleControlChange(channelNumber, controller, value) {
|
|
904
925
|
switch (controller) {
|
|
@@ -1171,10 +1192,10 @@ class MidyGM2 {
|
|
|
1171
1192
|
switch (data[3]) {
|
|
1172
1193
|
// case 1:
|
|
1173
1194
|
// // TODO
|
|
1174
|
-
// return this.
|
|
1195
|
+
// return this.setChannelPressure();
|
|
1175
1196
|
// case 3:
|
|
1176
1197
|
// // TODO
|
|
1177
|
-
// return this.
|
|
1198
|
+
// return this.setControlChange();
|
|
1178
1199
|
default:
|
|
1179
1200
|
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1180
1201
|
}
|
|
@@ -1193,20 +1214,25 @@ class MidyGM2 {
|
|
|
1193
1214
|
}
|
|
1194
1215
|
}
|
|
1195
1216
|
handleMasterVolumeSysEx(data) {
|
|
1196
|
-
const volume = (data[5] * 128 + data[4]
|
|
1217
|
+
const volume = (data[5] * 128 + data[4]) / 16383;
|
|
1197
1218
|
this.handleMasterVolume(volume);
|
|
1198
1219
|
}
|
|
1199
1220
|
handleMasterVolume(volume) {
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1221
|
+
if (volume < 0 && 1 < volume) {
|
|
1222
|
+
console.error("Master Volume is out of range");
|
|
1223
|
+
}
|
|
1224
|
+
else {
|
|
1225
|
+
const now = this.audioContext.currentTime;
|
|
1226
|
+
this.masterGain.gain.cancelScheduledValues(now);
|
|
1227
|
+
this.masterGain.gain.setValueAtTime(volume * volume, now);
|
|
1228
|
+
}
|
|
1203
1229
|
}
|
|
1204
1230
|
handleMasterFineTuningSysEx(data) {
|
|
1205
1231
|
const fineTuning = (data[5] * 128 + data[4] - 8192) / 8192;
|
|
1206
1232
|
this.handleMasterFineTuning(fineTuning);
|
|
1207
1233
|
}
|
|
1208
1234
|
handleMasterFineTuning(fineTuning) {
|
|
1209
|
-
if (fineTuning <
|
|
1235
|
+
if (fineTuning < -1 && 1 < fineTuning) {
|
|
1210
1236
|
console.error("Master Fine Tuning value is out of range");
|
|
1211
1237
|
}
|
|
1212
1238
|
else {
|
|
@@ -1294,3 +1320,16 @@ Object.defineProperty(MidyGM2, "effectSettings", {
|
|
|
1294
1320
|
pitchBendRange: 2,
|
|
1295
1321
|
}
|
|
1296
1322
|
});
|
|
1323
|
+
Object.defineProperty(MidyGM2, "controllerDestinationSettings", {
|
|
1324
|
+
enumerable: true,
|
|
1325
|
+
configurable: true,
|
|
1326
|
+
writable: true,
|
|
1327
|
+
value: {
|
|
1328
|
+
pitchControl: 0,
|
|
1329
|
+
filterCutoffControl: 0,
|
|
1330
|
+
amplitudeControl: 1,
|
|
1331
|
+
lfoPitchDepth: 0,
|
|
1332
|
+
lfoFilterDepth: 0,
|
|
1333
|
+
lfoAmplitudeDepth: 0,
|
|
1334
|
+
}
|
|
1335
|
+
});
|
package/script/midy-GMLite.d.ts
CHANGED
|
@@ -131,6 +131,8 @@ export class MidyGMLite {
|
|
|
131
131
|
connectNoteEffects(channel: any, gainNode: any): void;
|
|
132
132
|
cbToRatio(cb: any): number;
|
|
133
133
|
centToHz(cent: any): number;
|
|
134
|
+
calcSemitoneOffset(channel: any): any;
|
|
135
|
+
calcPlaybackRate(noteInfo: any, noteNumber: any, semitoneOffset: any): number;
|
|
134
136
|
createNoteAudioChain(channel: any, noteInfo: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<{
|
|
135
137
|
bufferSource: any;
|
|
136
138
|
gainNode: any;
|
|
@@ -143,10 +145,9 @@ export class MidyGMLite {
|
|
|
143
145
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
144
146
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
145
147
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
|
|
146
|
-
handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
|
|
147
148
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
148
|
-
|
|
149
|
-
handlePitchBend(channelNumber: any,
|
|
149
|
+
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
150
|
+
handlePitchBend(channelNumber: any, pitchBend: any): void;
|
|
150
151
|
handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
|
|
151
152
|
setModulation(channelNumber: any, modulation: any): void;
|
|
152
153
|
setVolume(channelNumber: any, volume: any): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAMA;IAmBE;;;;;;;;;;;;MAYE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA/CD,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;IA0BhB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;MAgBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,
|
|
1
|
+
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAMA;IAmBE;;;;;;;;;;;;MAYE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA/CD,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;IA0BhB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;MAgBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAyEC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED,sDAEC;IAED,2BAEC;IAED,4BAEC;IAED,sCAEC;IAED,8EAEC;IAED;;;;;OA8EC;IAED,kGAuCC;IAED,0EAGC;IAED,sIA4CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,0DAiBC;IAED,mFA+BC;IAED,yDAIC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,sCAKC;IAED,sDAMC;IAED,gDAEC;IAED,gDAEC;IAED,+DAcC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,sCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
|
package/script/midy-GMLite.js
CHANGED
|
@@ -226,9 +226,6 @@ class MidyGMLite {
|
|
|
226
226
|
if (event.startTime > t + this.lookAhead)
|
|
227
227
|
break;
|
|
228
228
|
switch (event.type) {
|
|
229
|
-
case "controller":
|
|
230
|
-
this.handleControlChange(event.channel, event.controllerType, event.value);
|
|
231
|
-
break;
|
|
232
229
|
case "noteOn":
|
|
233
230
|
if (event.velocity !== 0) {
|
|
234
231
|
await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
|
|
@@ -242,9 +239,15 @@ class MidyGMLite {
|
|
|
242
239
|
}
|
|
243
240
|
break;
|
|
244
241
|
}
|
|
242
|
+
case "controller":
|
|
243
|
+
this.handleControlChange(event.channel, event.controllerType, event.value);
|
|
244
|
+
break;
|
|
245
245
|
case "programChange":
|
|
246
246
|
this.handleProgramChange(event.channel, event.programNumber);
|
|
247
247
|
break;
|
|
248
|
+
case "pitchBend":
|
|
249
|
+
this.handlePitchBend(event.channel, event.value);
|
|
250
|
+
break;
|
|
248
251
|
case "sysEx":
|
|
249
252
|
this.handleSysEx(event.data);
|
|
250
253
|
}
|
|
@@ -481,12 +484,16 @@ class MidyGMLite {
|
|
|
481
484
|
centToHz(cent) {
|
|
482
485
|
return 8.176 * Math.pow(2, cent / 1200);
|
|
483
486
|
}
|
|
487
|
+
calcSemitoneOffset(channel) {
|
|
488
|
+
return channel.pitchBend * channel.pitchBendRange + tuning;
|
|
489
|
+
}
|
|
490
|
+
calcPlaybackRate(noteInfo, noteNumber, semitoneOffset) {
|
|
491
|
+
return noteInfo.playbackRate(noteNumber) * Math.pow(2, semitoneOffset / 12);
|
|
492
|
+
}
|
|
484
493
|
async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
|
|
485
|
-
const semitoneOffset = channel.pitchBend * channel.pitchBendRange;
|
|
486
|
-
const playbackRate = noteInfo.playbackRate(noteNumber) *
|
|
487
|
-
Math.pow(2, semitoneOffset / 12);
|
|
488
494
|
const bufferSource = await this.createNoteBufferNode(noteInfo, isSF3);
|
|
489
|
-
|
|
495
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
496
|
+
bufferSource.playbackRate.value = this.calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
|
|
490
497
|
// volume envelope
|
|
491
498
|
const gainNode = new GainNode(this.audioContext, {
|
|
492
499
|
gain: 0,
|
|
@@ -652,46 +659,37 @@ class MidyGMLite {
|
|
|
652
659
|
return this.releaseNote(channelNumber, data1, data2);
|
|
653
660
|
case 0x90:
|
|
654
661
|
return this.noteOn(channelNumber, data1, data2);
|
|
655
|
-
case 0xA0:
|
|
656
|
-
return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
|
|
657
662
|
case 0xB0:
|
|
658
663
|
return this.handleControlChange(channelNumber, data1, data2);
|
|
659
664
|
case 0xC0:
|
|
660
665
|
return this.handleProgramChange(channelNumber, data1);
|
|
661
|
-
case 0xD0:
|
|
662
|
-
return this.handleChannelPressure(channelNumber, data1);
|
|
663
666
|
case 0xE0:
|
|
664
|
-
return this.
|
|
667
|
+
return this.handlePitchBendMessage(channelNumber, data1, data2);
|
|
665
668
|
default:
|
|
666
669
|
console.warn(`Unsupported MIDI message: ${messageType.toString(16)}`);
|
|
667
670
|
}
|
|
668
671
|
}
|
|
669
|
-
handlePolyphonicKeyPressure(channelNumber, noteNumber, pressure) {
|
|
670
|
-
const now = this.audioContext.currentTime;
|
|
671
|
-
const channel = this.channels[channelNumber];
|
|
672
|
-
const scheduledNotes = channel.scheduledNotes.get(noteNumber);
|
|
673
|
-
pressure /= 127;
|
|
674
|
-
if (scheduledNotes) {
|
|
675
|
-
scheduledNotes.forEach((scheduledNote) => {
|
|
676
|
-
if (scheduledNote) {
|
|
677
|
-
const { initialAttenuation } = scheduledNote.noteInfo;
|
|
678
|
-
const gain = this.cbToRatio(-initialAttenuation) * pressure;
|
|
679
|
-
scheduledNote.gainNode.gain.cancelScheduledValues(now);
|
|
680
|
-
scheduledNote.gainNode.gain.setValueAtTime(gain, now);
|
|
681
|
-
}
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
672
|
handleProgramChange(channelNumber, program) {
|
|
686
673
|
const channel = this.channels[channelNumber];
|
|
687
674
|
channel.program = program;
|
|
688
675
|
}
|
|
689
|
-
|
|
690
|
-
|
|
676
|
+
handlePitchBendMessage(channelNumber, lsb, msb) {
|
|
677
|
+
const pitchBend = msb * 128 + lsb;
|
|
678
|
+
this.handlePitchBend(channelNumber, pitchBend);
|
|
691
679
|
}
|
|
692
|
-
handlePitchBend(channelNumber,
|
|
693
|
-
const
|
|
694
|
-
this.channels[channelNumber]
|
|
680
|
+
handlePitchBend(channelNumber, pitchBend) {
|
|
681
|
+
const now = this.audioContext.currentTime;
|
|
682
|
+
const channel = this.channels[channelNumber];
|
|
683
|
+
channel.pitchBend = (pitchBend - 8192) / 8192;
|
|
684
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
685
|
+
const activeNotes = this.getActiveNotes(channel);
|
|
686
|
+
activeNotes.forEach((activeNote) => {
|
|
687
|
+
const { bufferSource, noteInfo, noteNumber } = activeNote;
|
|
688
|
+
const playbackRate = calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
|
|
689
|
+
bufferSource.playbackRate
|
|
690
|
+
.cancelScheduledValues(now)
|
|
691
|
+
.setValueAtTime(playbackRate * pressure, now);
|
|
692
|
+
});
|
|
695
693
|
}
|
|
696
694
|
handleControlChange(channelNumber, controller, value) {
|
|
697
695
|
switch (controller) {
|
|
@@ -851,13 +849,18 @@ class MidyGMLite {
|
|
|
851
849
|
}
|
|
852
850
|
}
|
|
853
851
|
handleMasterVolumeSysEx(data) {
|
|
854
|
-
const volume = (data[5] * 128 + data[4]
|
|
852
|
+
const volume = (data[5] * 128 + data[4]) / 16383;
|
|
855
853
|
this.handleMasterVolume(volume);
|
|
856
854
|
}
|
|
857
855
|
handleMasterVolume(volume) {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
856
|
+
if (volume < 0 && 1 < volume) {
|
|
857
|
+
console.error("Master Volume is out of range");
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
const now = this.audioContext.currentTime;
|
|
861
|
+
this.masterGain.gain.cancelScheduledValues(now);
|
|
862
|
+
this.masterGain.gain.setValueAtTime(volume * volume, now);
|
|
863
|
+
}
|
|
861
864
|
}
|
|
862
865
|
handleExclusiveMessage(data) {
|
|
863
866
|
console.warn(`Unsupported Exclusive Message ${data}`);
|
package/script/midy.d.ts
CHANGED
|
@@ -32,6 +32,14 @@ export class Midy {
|
|
|
32
32
|
channelPressure: number;
|
|
33
33
|
pitchBendRange: number;
|
|
34
34
|
};
|
|
35
|
+
static controllerDestinationSettings: {
|
|
36
|
+
pitchControl: number;
|
|
37
|
+
filterCutoffControl: number;
|
|
38
|
+
amplitudeControl: number;
|
|
39
|
+
lfoPitchDepth: number;
|
|
40
|
+
lfoFilterDepth: number;
|
|
41
|
+
lfoAmplitudeDepth: number;
|
|
42
|
+
};
|
|
35
43
|
constructor(audioContext: any);
|
|
36
44
|
ticksPerBeat: number;
|
|
37
45
|
totalTime: number;
|
|
@@ -60,6 +68,22 @@ export class Midy {
|
|
|
60
68
|
channels: {
|
|
61
69
|
scheduledNotes: Map<any, any>;
|
|
62
70
|
sostenutoNotes: Map<any, any>;
|
|
71
|
+
polyphonicKeyPressure: {
|
|
72
|
+
pitchControl: number;
|
|
73
|
+
filterCutoffControl: number;
|
|
74
|
+
amplitudeControl: number;
|
|
75
|
+
lfoPitchDepth: number;
|
|
76
|
+
lfoFilterDepth: number;
|
|
77
|
+
lfoAmplitudeDepth: number;
|
|
78
|
+
};
|
|
79
|
+
channelPressure: {
|
|
80
|
+
pitchControl: number;
|
|
81
|
+
filterCutoffControl: number;
|
|
82
|
+
amplitudeControl: number;
|
|
83
|
+
lfoPitchDepth: number;
|
|
84
|
+
lfoFilterDepth: number;
|
|
85
|
+
lfoAmplitudeDepth: number;
|
|
86
|
+
};
|
|
63
87
|
gainNode: any;
|
|
64
88
|
pannerNode: any;
|
|
65
89
|
modulationEffect: {
|
|
@@ -84,7 +108,6 @@ export class Midy {
|
|
|
84
108
|
softPedal: number;
|
|
85
109
|
rpnMSB: number;
|
|
86
110
|
rpnLSB: number;
|
|
87
|
-
channelPressure: number;
|
|
88
111
|
pitchBendRange: number;
|
|
89
112
|
currentBufferSource: null;
|
|
90
113
|
volume: number;
|
|
@@ -131,6 +154,22 @@ export class Midy {
|
|
|
131
154
|
createChannels(audioContext: any): {
|
|
132
155
|
scheduledNotes: Map<any, any>;
|
|
133
156
|
sostenutoNotes: Map<any, any>;
|
|
157
|
+
polyphonicKeyPressure: {
|
|
158
|
+
pitchControl: number;
|
|
159
|
+
filterCutoffControl: number;
|
|
160
|
+
amplitudeControl: number;
|
|
161
|
+
lfoPitchDepth: number;
|
|
162
|
+
lfoFilterDepth: number;
|
|
163
|
+
lfoAmplitudeDepth: number;
|
|
164
|
+
};
|
|
165
|
+
channelPressure: {
|
|
166
|
+
pitchControl: number;
|
|
167
|
+
filterCutoffControl: number;
|
|
168
|
+
amplitudeControl: number;
|
|
169
|
+
lfoPitchDepth: number;
|
|
170
|
+
lfoFilterDepth: number;
|
|
171
|
+
lfoAmplitudeDepth: number;
|
|
172
|
+
};
|
|
134
173
|
gainNode: any;
|
|
135
174
|
pannerNode: any;
|
|
136
175
|
modulationEffect: {
|
|
@@ -155,7 +194,6 @@ export class Midy {
|
|
|
155
194
|
softPedal: number;
|
|
156
195
|
rpnMSB: number;
|
|
157
196
|
rpnLSB: number;
|
|
158
|
-
channelPressure: number;
|
|
159
197
|
pitchBendRange: number;
|
|
160
198
|
currentBufferSource: null;
|
|
161
199
|
volume: number;
|
|
@@ -216,10 +254,13 @@ export class Midy {
|
|
|
216
254
|
connectNoteEffects(channel: any, gainNode: any): void;
|
|
217
255
|
cbToRatio(cb: any): number;
|
|
218
256
|
centToHz(cent: any): number;
|
|
257
|
+
calcSemitoneOffset(channel: any): any;
|
|
258
|
+
calcPlaybackRate(noteInfo: any, noteNumber: any, semitoneOffset: any): number;
|
|
219
259
|
createNoteAudioChain(channel: any, noteInfo: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<{
|
|
220
260
|
bufferSource: any;
|
|
221
261
|
gainNode: any;
|
|
222
262
|
filterNode: any;
|
|
263
|
+
lfoGain: any;
|
|
223
264
|
}>;
|
|
224
265
|
calcBank(channel: any, channelNumber: any): any;
|
|
225
266
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
@@ -232,7 +273,8 @@ export class Midy {
|
|
|
232
273
|
handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
|
|
233
274
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
234
275
|
handleChannelPressure(channelNumber: any, pressure: any): void;
|
|
235
|
-
|
|
276
|
+
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
277
|
+
handlePitchBend(channelNumber: any, pitchBend: any): void;
|
|
236
278
|
handleControlChange(channelNumber: any, controller: any, value: any): any;
|
|
237
279
|
setBankMSB(channelNumber: any, msb: any): void;
|
|
238
280
|
setModulation(channelNumber: any, modulation: any): void;
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAMA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF,+BAMC;
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAMA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,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;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;;;;MAuBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiBC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EAyDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA2GC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED;;;;MAoCC;IAED;;;;;MA2CC;IAED,sDA2BC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,8EAEC;IAED;;;;;OAqFC;IAED,gDAQC;IAED,kGAgDC;IAED,0EAGC;IAED,sIA6CC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,gEAqBC;IAED,sFAcC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,0DAiBC;IAED,0EAkEC;IAED,+CAEC;IAED,yDAIC;IAED,iEAEC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,+CAEC;IAED,sCAKC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAUC;IAED,uDAGC;IAED,2DAOC;IAED,6DAOC;IAED,6DASC;IAED,4CAkBC;IAED,4CAkBC;IAED,gDAEC;IAED,gDAEC;IAGD,+DAuBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,sCAQC;IAED,6CAGC;IAED,8CAMC;IAED,+CAGC;IAED,kDAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
|