@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/esm/midy-GM1.d.ts
CHANGED
|
@@ -137,6 +137,8 @@ export class MidyGM1 {
|
|
|
137
137
|
connectNoteEffects(channel: any, gainNode: any): void;
|
|
138
138
|
cbToRatio(cb: any): number;
|
|
139
139
|
centToHz(cent: any): number;
|
|
140
|
+
calcSemitoneOffset(channel: any): any;
|
|
141
|
+
calcPlaybackRate(noteInfo: any, noteNumber: any, semitoneOffset: any): number;
|
|
140
142
|
createNoteAudioChain(channel: any, noteInfo: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<{
|
|
141
143
|
bufferSource: any;
|
|
142
144
|
gainNode: any;
|
|
@@ -149,10 +151,9 @@ export class MidyGM1 {
|
|
|
149
151
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
150
152
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
151
153
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
|
|
152
|
-
handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
|
|
153
154
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
154
|
-
|
|
155
|
-
handlePitchBend(channelNumber: any,
|
|
155
|
+
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
156
|
+
handlePitchBend(channelNumber: any, pitchBend: any): void;
|
|
156
157
|
handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
|
|
157
158
|
setModulation(channelNumber: any, modulation: any): void;
|
|
158
159
|
setVolume(channelNumber: any, volume: any): void;
|
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":"AAMA;IAmBE;;;;;;;;;;;;;;MAcE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAjDD,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;IA4BhB,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-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAMA;IAmBE;;;;;;;;;;;;;;MAcE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAjDD,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;IA4BhB,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,sCAGC;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,+DAoBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,sCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
|
package/esm/midy-GM1.js
CHANGED
|
@@ -223,9 +223,6 @@ export class MidyGM1 {
|
|
|
223
223
|
if (event.startTime > t + this.lookAhead)
|
|
224
224
|
break;
|
|
225
225
|
switch (event.type) {
|
|
226
|
-
case "controller":
|
|
227
|
-
this.handleControlChange(event.channel, event.controllerType, event.value);
|
|
228
|
-
break;
|
|
229
226
|
case "noteOn":
|
|
230
227
|
if (event.velocity !== 0) {
|
|
231
228
|
await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
|
|
@@ -239,9 +236,15 @@ export class MidyGM1 {
|
|
|
239
236
|
}
|
|
240
237
|
break;
|
|
241
238
|
}
|
|
239
|
+
case "controller":
|
|
240
|
+
this.handleControlChange(event.channel, event.controllerType, event.value);
|
|
241
|
+
break;
|
|
242
242
|
case "programChange":
|
|
243
243
|
this.handleProgramChange(event.channel, event.programNumber);
|
|
244
244
|
break;
|
|
245
|
+
case "pitchBend":
|
|
246
|
+
this.handlePitchBend(event.channel, event.value);
|
|
247
|
+
break;
|
|
245
248
|
case "sysEx":
|
|
246
249
|
this.handleSysEx(event.data);
|
|
247
250
|
}
|
|
@@ -478,13 +481,17 @@ export class MidyGM1 {
|
|
|
478
481
|
centToHz(cent) {
|
|
479
482
|
return 8.176 * Math.pow(2, cent / 1200);
|
|
480
483
|
}
|
|
481
|
-
|
|
484
|
+
calcSemitoneOffset(channel) {
|
|
482
485
|
const tuning = channel.coarseTuning + channel.fineTuning;
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
+
return channel.pitchBend * channel.pitchBendRange + tuning;
|
|
487
|
+
}
|
|
488
|
+
calcPlaybackRate(noteInfo, noteNumber, semitoneOffset) {
|
|
489
|
+
return noteInfo.playbackRate(noteNumber) * Math.pow(2, semitoneOffset / 12);
|
|
490
|
+
}
|
|
491
|
+
async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
|
|
486
492
|
const bufferSource = await this.createNoteBufferNode(noteInfo, isSF3);
|
|
487
|
-
|
|
493
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
494
|
+
bufferSource.playbackRate.value = this.calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
|
|
488
495
|
// volume envelope
|
|
489
496
|
const gainNode = new GainNode(this.audioContext, {
|
|
490
497
|
gain: 0,
|
|
@@ -650,46 +657,37 @@ export class MidyGM1 {
|
|
|
650
657
|
return this.releaseNote(channelNumber, data1, data2);
|
|
651
658
|
case 0x90:
|
|
652
659
|
return this.noteOn(channelNumber, data1, data2);
|
|
653
|
-
case 0xA0:
|
|
654
|
-
return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
|
|
655
660
|
case 0xB0:
|
|
656
661
|
return this.handleControlChange(channelNumber, data1, data2);
|
|
657
662
|
case 0xC0:
|
|
658
663
|
return this.handleProgramChange(channelNumber, data1);
|
|
659
|
-
case 0xD0:
|
|
660
|
-
return this.handleChannelPressure(channelNumber, data1);
|
|
661
664
|
case 0xE0:
|
|
662
|
-
return this.
|
|
665
|
+
return this.handlePitchBendMessage(channelNumber, data1, data2);
|
|
663
666
|
default:
|
|
664
667
|
console.warn(`Unsupported MIDI message: ${messageType.toString(16)}`);
|
|
665
668
|
}
|
|
666
669
|
}
|
|
667
|
-
handlePolyphonicKeyPressure(channelNumber, noteNumber, pressure) {
|
|
668
|
-
const now = this.audioContext.currentTime;
|
|
669
|
-
const channel = this.channels[channelNumber];
|
|
670
|
-
const scheduledNotes = channel.scheduledNotes.get(noteNumber);
|
|
671
|
-
pressure /= 127;
|
|
672
|
-
if (scheduledNotes) {
|
|
673
|
-
scheduledNotes.forEach((scheduledNote) => {
|
|
674
|
-
if (scheduledNote) {
|
|
675
|
-
const { initialAttenuation } = scheduledNote.noteInfo;
|
|
676
|
-
const gain = this.cbToRatio(-initialAttenuation) * pressure;
|
|
677
|
-
scheduledNote.gainNode.gain.cancelScheduledValues(now);
|
|
678
|
-
scheduledNote.gainNode.gain.setValueAtTime(gain, now);
|
|
679
|
-
}
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
670
|
handleProgramChange(channelNumber, program) {
|
|
684
671
|
const channel = this.channels[channelNumber];
|
|
685
672
|
channel.program = program;
|
|
686
673
|
}
|
|
687
|
-
|
|
688
|
-
|
|
674
|
+
handlePitchBendMessage(channelNumber, lsb, msb) {
|
|
675
|
+
const pitchBend = msb * 128 + lsb;
|
|
676
|
+
this.handlePitchBend(channelNumber, pitchBend);
|
|
689
677
|
}
|
|
690
|
-
handlePitchBend(channelNumber,
|
|
691
|
-
const
|
|
692
|
-
this.channels[channelNumber]
|
|
678
|
+
handlePitchBend(channelNumber, pitchBend) {
|
|
679
|
+
const now = this.audioContext.currentTime;
|
|
680
|
+
const channel = this.channels[channelNumber];
|
|
681
|
+
channel.pitchBend = (pitchBend - 8192) / 8192;
|
|
682
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
683
|
+
const activeNotes = this.getActiveNotes(channel);
|
|
684
|
+
activeNotes.forEach((activeNote) => {
|
|
685
|
+
const { bufferSource, noteInfo, noteNumber } = activeNote;
|
|
686
|
+
const playbackRate = calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
|
|
687
|
+
bufferSource.playbackRate
|
|
688
|
+
.cancelScheduledValues(now)
|
|
689
|
+
.setValueAtTime(playbackRate * pressure, now);
|
|
690
|
+
});
|
|
693
691
|
}
|
|
694
692
|
handleControlChange(channelNumber, controller, value) {
|
|
695
693
|
switch (controller) {
|
|
@@ -855,13 +853,18 @@ export class MidyGM1 {
|
|
|
855
853
|
}
|
|
856
854
|
}
|
|
857
855
|
handleMasterVolumeSysEx(data) {
|
|
858
|
-
const volume = (data[5] * 128 + data[4]
|
|
856
|
+
const volume = (data[5] * 128 + data[4]) / 16383;
|
|
859
857
|
this.handleMasterVolume(volume);
|
|
860
858
|
}
|
|
861
859
|
handleMasterVolume(volume) {
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
860
|
+
if (volume < 0 && 1 < volume) {
|
|
861
|
+
console.error("Master Volume is out of range");
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
const now = this.audioContext.currentTime;
|
|
865
|
+
this.masterGain.gain.cancelScheduledValues(now);
|
|
866
|
+
this.masterGain.gain.setValueAtTime(volume * volume, now);
|
|
867
|
+
}
|
|
865
868
|
}
|
|
866
869
|
handleExclusiveMessage(data) {
|
|
867
870
|
console.warn(`Unsupported Exclusive Message ${data}`);
|
package/esm/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/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":"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/esm/midy-GM2.js
CHANGED
|
@@ -201,11 +201,14 @@ export class MidyGM2 {
|
|
|
201
201
|
createChannels(audioContext) {
|
|
202
202
|
const channels = Array.from({ length: 16 }, () => {
|
|
203
203
|
return {
|
|
204
|
-
...
|
|
205
|
-
...
|
|
204
|
+
...Midy.channelSettings,
|
|
205
|
+
...Midy.effectSettings,
|
|
206
206
|
...this.setChannelAudioNodes(audioContext),
|
|
207
207
|
scheduledNotes: new Map(),
|
|
208
208
|
sostenutoNotes: new Map(),
|
|
209
|
+
channelPressure: {
|
|
210
|
+
...Midy.controllerDestinationSettings,
|
|
211
|
+
},
|
|
209
212
|
};
|
|
210
213
|
});
|
|
211
214
|
return channels;
|
|
@@ -260,9 +263,6 @@ export class MidyGM2 {
|
|
|
260
263
|
if (event.startTime > t + this.lookAhead)
|
|
261
264
|
break;
|
|
262
265
|
switch (event.type) {
|
|
263
|
-
case "controller":
|
|
264
|
-
this.handleControlChange(this.omni ? 0 : event.channel, event.controllerType, event.value);
|
|
265
|
-
break;
|
|
266
266
|
case "noteOn":
|
|
267
267
|
if (event.velocity !== 0) {
|
|
268
268
|
await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
|
|
@@ -276,9 +276,18 @@ export class MidyGM2 {
|
|
|
276
276
|
}
|
|
277
277
|
break;
|
|
278
278
|
}
|
|
279
|
+
case "controller":
|
|
280
|
+
this.handleControlChange(this.omni ? 0 : event.channel, event.controllerType, event.value);
|
|
281
|
+
break;
|
|
279
282
|
case "programChange":
|
|
280
283
|
this.handleProgramChange(event.channel, event.programNumber);
|
|
281
284
|
break;
|
|
285
|
+
case "channelAftertouch":
|
|
286
|
+
this.handleChannelPressure(event.channel, event.amount);
|
|
287
|
+
break;
|
|
288
|
+
case "pitchBend":
|
|
289
|
+
this.handlePitchBend(event.channel, event.value);
|
|
290
|
+
break;
|
|
282
291
|
case "sysEx":
|
|
283
292
|
this.handleSysEx(event.data);
|
|
284
293
|
}
|
|
@@ -642,15 +651,19 @@ export class MidyGM2 {
|
|
|
642
651
|
centToHz(cent) {
|
|
643
652
|
return 8.176 * Math.pow(2, cent / 1200);
|
|
644
653
|
}
|
|
645
|
-
|
|
654
|
+
calcSemitoneOffset(channel) {
|
|
646
655
|
const masterTuning = this.masterCoarseTuning + this.masterFineTuning;
|
|
647
656
|
const channelTuning = channel.coarseTuning + channel.fineTuning;
|
|
648
657
|
const tuning = masterTuning + channelTuning;
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
658
|
+
return channel.pitchBend * channel.pitchBendRange + tuning;
|
|
659
|
+
}
|
|
660
|
+
calcPlaybackRate(noteInfo, noteNumber, semitoneOffset) {
|
|
661
|
+
return noteInfo.playbackRate(noteNumber) * Math.pow(2, semitoneOffset / 12);
|
|
662
|
+
}
|
|
663
|
+
async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
|
|
652
664
|
const bufferSource = await this.createNoteBufferNode(noteInfo, isSF3);
|
|
653
|
-
|
|
665
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
666
|
+
bufferSource.playbackRate.value = this.calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
|
|
654
667
|
// volume envelope
|
|
655
668
|
const gainNode = new GainNode(this.audioContext, {
|
|
656
669
|
gain: 0,
|
|
@@ -855,8 +868,6 @@ export class MidyGM2 {
|
|
|
855
868
|
return this.releaseNote(channelNumber, data1, data2);
|
|
856
869
|
case 0x90:
|
|
857
870
|
return this.noteOn(channelNumber, data1, data2);
|
|
858
|
-
case 0xA0:
|
|
859
|
-
return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
|
|
860
871
|
case 0xB0:
|
|
861
872
|
return this.handleControlChange(channelNumber, data1, data2);
|
|
862
873
|
case 0xC0:
|
|
@@ -864,38 +875,48 @@ export class MidyGM2 {
|
|
|
864
875
|
case 0xD0:
|
|
865
876
|
return this.handleChannelPressure(channelNumber, data1);
|
|
866
877
|
case 0xE0:
|
|
867
|
-
return this.
|
|
878
|
+
return this.handlePitchBendMessage(channelNumber, data1, data2);
|
|
868
879
|
default:
|
|
869
880
|
console.warn(`Unsupported MIDI message: ${messageType.toString(16)}`);
|
|
870
881
|
}
|
|
871
882
|
}
|
|
872
|
-
handlePolyphonicKeyPressure(channelNumber, noteNumber, pressure) {
|
|
873
|
-
const now = this.audioContext.currentTime;
|
|
874
|
-
const channel = this.channels[channelNumber];
|
|
875
|
-
const scheduledNotes = channel.scheduledNotes.get(noteNumber);
|
|
876
|
-
pressure /= 127;
|
|
877
|
-
if (scheduledNotes) {
|
|
878
|
-
scheduledNotes.forEach((scheduledNote) => {
|
|
879
|
-
if (scheduledNote) {
|
|
880
|
-
const { initialAttenuation } = scheduledNote.noteInfo;
|
|
881
|
-
const gain = this.cbToRatio(-initialAttenuation) * pressure;
|
|
882
|
-
scheduledNote.gainNode.gain.cancelScheduledValues(now);
|
|
883
|
-
scheduledNote.gainNode.gain.setValueAtTime(gain, now);
|
|
884
|
-
}
|
|
885
|
-
});
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
883
|
handleProgramChange(channelNumber, program) {
|
|
889
884
|
const channel = this.channels[channelNumber];
|
|
890
885
|
channel.bank = channel.bankMSB * 128 + channel.bankLSB;
|
|
891
886
|
channel.program = program;
|
|
892
887
|
}
|
|
893
888
|
handleChannelPressure(channelNumber, pressure) {
|
|
894
|
-
this.
|
|
889
|
+
const now = this.audioContext.currentTime;
|
|
890
|
+
const channel = this.channels[channelNumber];
|
|
891
|
+
pressure /= 64;
|
|
892
|
+
channel.channelPressure = pressure;
|
|
893
|
+
const activeNotes = this.getActiveNotes(channel);
|
|
894
|
+
if (channel.channelPressure.amplitudeControl !== 1) {
|
|
895
|
+
activeNotes.forEach((activeNote) => {
|
|
896
|
+
const gain = activeNote.gainNode.gain.value;
|
|
897
|
+
activeNote.gainNode.gain
|
|
898
|
+
.cancelScheduledValues(now)
|
|
899
|
+
.setValueAtTime(gain * pressure, now);
|
|
900
|
+
});
|
|
901
|
+
}
|
|
895
902
|
}
|
|
896
|
-
|
|
897
|
-
const pitchBend =
|
|
898
|
-
this.
|
|
903
|
+
handlePitchBendMessage(channelNumber, lsb, msb) {
|
|
904
|
+
const pitchBend = msb * 128 + lsb;
|
|
905
|
+
this.handlePitchBend(channelNumber, pitchBend);
|
|
906
|
+
}
|
|
907
|
+
handlePitchBend(channelNumber, pitchBend) {
|
|
908
|
+
const now = this.audioContext.currentTime;
|
|
909
|
+
const channel = this.channels[channelNumber];
|
|
910
|
+
channel.pitchBend = (pitchBend - 8192) / 8192;
|
|
911
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
912
|
+
const activeNotes = this.getActiveNotes(channel);
|
|
913
|
+
activeNotes.forEach((activeNote) => {
|
|
914
|
+
const { bufferSource, noteInfo, noteNumber } = activeNote;
|
|
915
|
+
const playbackRate = calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
|
|
916
|
+
bufferSource.playbackRate
|
|
917
|
+
.cancelScheduledValues(now)
|
|
918
|
+
.setValueAtTime(playbackRate * pressure, now);
|
|
919
|
+
});
|
|
899
920
|
}
|
|
900
921
|
handleControlChange(channelNumber, controller, value) {
|
|
901
922
|
switch (controller) {
|
|
@@ -1168,10 +1189,10 @@ export class MidyGM2 {
|
|
|
1168
1189
|
switch (data[3]) {
|
|
1169
1190
|
// case 1:
|
|
1170
1191
|
// // TODO
|
|
1171
|
-
// return this.
|
|
1192
|
+
// return this.setChannelPressure();
|
|
1172
1193
|
// case 3:
|
|
1173
1194
|
// // TODO
|
|
1174
|
-
// return this.
|
|
1195
|
+
// return this.setControlChange();
|
|
1175
1196
|
default:
|
|
1176
1197
|
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1177
1198
|
}
|
|
@@ -1190,20 +1211,25 @@ export class MidyGM2 {
|
|
|
1190
1211
|
}
|
|
1191
1212
|
}
|
|
1192
1213
|
handleMasterVolumeSysEx(data) {
|
|
1193
|
-
const volume = (data[5] * 128 + data[4]
|
|
1214
|
+
const volume = (data[5] * 128 + data[4]) / 16383;
|
|
1194
1215
|
this.handleMasterVolume(volume);
|
|
1195
1216
|
}
|
|
1196
1217
|
handleMasterVolume(volume) {
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1218
|
+
if (volume < 0 && 1 < volume) {
|
|
1219
|
+
console.error("Master Volume is out of range");
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
const now = this.audioContext.currentTime;
|
|
1223
|
+
this.masterGain.gain.cancelScheduledValues(now);
|
|
1224
|
+
this.masterGain.gain.setValueAtTime(volume * volume, now);
|
|
1225
|
+
}
|
|
1200
1226
|
}
|
|
1201
1227
|
handleMasterFineTuningSysEx(data) {
|
|
1202
1228
|
const fineTuning = (data[5] * 128 + data[4] - 8192) / 8192;
|
|
1203
1229
|
this.handleMasterFineTuning(fineTuning);
|
|
1204
1230
|
}
|
|
1205
1231
|
handleMasterFineTuning(fineTuning) {
|
|
1206
|
-
if (fineTuning <
|
|
1232
|
+
if (fineTuning < -1 && 1 < fineTuning) {
|
|
1207
1233
|
console.error("Master Fine Tuning value is out of range");
|
|
1208
1234
|
}
|
|
1209
1235
|
else {
|
|
@@ -1290,3 +1316,16 @@ Object.defineProperty(MidyGM2, "effectSettings", {
|
|
|
1290
1316
|
pitchBendRange: 2,
|
|
1291
1317
|
}
|
|
1292
1318
|
});
|
|
1319
|
+
Object.defineProperty(MidyGM2, "controllerDestinationSettings", {
|
|
1320
|
+
enumerable: true,
|
|
1321
|
+
configurable: true,
|
|
1322
|
+
writable: true,
|
|
1323
|
+
value: {
|
|
1324
|
+
pitchControl: 0,
|
|
1325
|
+
filterCutoffControl: 0,
|
|
1326
|
+
amplitudeControl: 1,
|
|
1327
|
+
lfoPitchDepth: 0,
|
|
1328
|
+
lfoFilterDepth: 0,
|
|
1329
|
+
lfoAmplitudeDepth: 0,
|
|
1330
|
+
}
|
|
1331
|
+
});
|
package/esm/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;
|
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":"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"}
|