@marmooo/midy 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.4 → soundfont-parser@0.0.6}/+esm.d.ts +16 -20
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +1 -0
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +180 -0
- package/esm/midy-GM1.d.ts +36 -8
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +87 -89
- package/esm/midy-GM2.d.ts +65 -10
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +233 -154
- package/esm/midy-GMLite.d.ts +36 -8
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +87 -89
- package/esm/midy.d.ts +85 -10
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +254 -174
- package/package.json +1 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.4 → soundfont-parser@0.0.6}/+esm.d.ts +16 -20
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +1 -0
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +190 -0
- package/script/midy-GM1.d.ts +36 -8
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +87 -89
- package/script/midy-GM2.d.ts +65 -10
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +233 -154
- package/script/midy-GMLite.d.ts +36 -8
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +87 -89
- package/script/midy.d.ts +85 -10
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +254 -174
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +0 -1
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.js +0 -162
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +0 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.js +0 -169
package/script/midy-GMLite.d.ts
CHANGED
|
@@ -37,6 +37,20 @@ export class MidyGMLite {
|
|
|
37
37
|
notePromises: any[];
|
|
38
38
|
audioContext: any;
|
|
39
39
|
masterGain: any;
|
|
40
|
+
controlChangeHandlers: {
|
|
41
|
+
1: (channelNumber: any, modulation: any) => void;
|
|
42
|
+
6: (channelNumber: any, value: any) => void;
|
|
43
|
+
7: (channelNumber: any, volume: any) => void;
|
|
44
|
+
10: (channelNumber: any, pan: any) => void;
|
|
45
|
+
11: (channelNumber: any, expression: any) => void;
|
|
46
|
+
38: (channelNumber: any, value: any) => void;
|
|
47
|
+
64: (channelNumber: any, value: any) => void;
|
|
48
|
+
100: (channelNumber: any, value: any) => void;
|
|
49
|
+
101: (channelNumber: any, value: any) => void;
|
|
50
|
+
120: (channelNumber: any) => Promise<void>;
|
|
51
|
+
121: (channelNumber: any) => void;
|
|
52
|
+
123: (channelNumber: any) => Promise<void>;
|
|
53
|
+
};
|
|
40
54
|
channels: any[];
|
|
41
55
|
initSoundFontTable(): any[];
|
|
42
56
|
addSoundFont(soundFont: any): void;
|
|
@@ -50,7 +64,6 @@ export class MidyGMLite {
|
|
|
50
64
|
createChannels(audioContext: any): any[];
|
|
51
65
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
52
66
|
createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
|
|
53
|
-
convertToFloat32Array(uint8Array: any): Float32Array;
|
|
54
67
|
scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
|
|
55
68
|
getQueueIndex(second: any): number;
|
|
56
69
|
playNotes(): Promise<any>;
|
|
@@ -60,8 +73,8 @@ export class MidyGMLite {
|
|
|
60
73
|
instruments: Set<any>;
|
|
61
74
|
timeline: any[];
|
|
62
75
|
};
|
|
63
|
-
stopChannelNotes(channelNumber: any, velocity: any,
|
|
64
|
-
stopNotes(velocity: any,
|
|
76
|
+
stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
|
|
77
|
+
stopNotes(velocity: any, force: any): Promise<any[]>;
|
|
65
78
|
start(): Promise<void>;
|
|
66
79
|
stop(): void;
|
|
67
80
|
pause(): void;
|
|
@@ -83,14 +96,29 @@ export class MidyGMLite {
|
|
|
83
96
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
84
97
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
85
98
|
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
stopNote(stopTime: any, endTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
100
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, force: any): void;
|
|
101
|
+
releaseNote(channelNumber: any, noteNumber: any, velocity: any): void;
|
|
88
102
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
89
|
-
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<
|
|
103
|
+
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<void>;
|
|
90
104
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
91
105
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
92
106
|
setPitchBend(channelNumber: any, pitchBend: any): void;
|
|
93
|
-
|
|
107
|
+
createControlChangeHandlers(): {
|
|
108
|
+
1: (channelNumber: any, modulation: any) => void;
|
|
109
|
+
6: (channelNumber: any, value: any) => void;
|
|
110
|
+
7: (channelNumber: any, volume: any) => void;
|
|
111
|
+
10: (channelNumber: any, pan: any) => void;
|
|
112
|
+
11: (channelNumber: any, expression: any) => void;
|
|
113
|
+
38: (channelNumber: any, value: any) => void;
|
|
114
|
+
64: (channelNumber: any, value: any) => void;
|
|
115
|
+
100: (channelNumber: any, value: any) => void;
|
|
116
|
+
101: (channelNumber: any, value: any) => void;
|
|
117
|
+
120: (channelNumber: any) => Promise<void>;
|
|
118
|
+
121: (channelNumber: any) => void;
|
|
119
|
+
123: (channelNumber: any) => Promise<void>;
|
|
120
|
+
};
|
|
121
|
+
handleControlChange(channelNumber: any, controller: any, value: any): void;
|
|
94
122
|
updateModulation(channel: any): void;
|
|
95
123
|
setModulationDepth(channelNumber: any, modulation: any): void;
|
|
96
124
|
setVolume(channelNumber: any, volume: any): void;
|
|
@@ -101,7 +129,7 @@ export class MidyGMLite {
|
|
|
101
129
|
setPan(channelNumber: any, pan: any): void;
|
|
102
130
|
setExpression(channelNumber: any, expression: any): void;
|
|
103
131
|
dataEntryLSB(channelNumber: any, value: any): void;
|
|
104
|
-
|
|
132
|
+
updateChannelVolume(channel: any): void;
|
|
105
133
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
106
134
|
handleRPN(channelNumber: any): void;
|
|
107
135
|
setRPNMSB(channelNumber: any, value: any): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+
|
|
1
|
+
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAOC;IA7CD,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IAuBhB,kBAAgC;IAChC,gBAA4C;IAC5C;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,+DAuBC;IAED,mEAWC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;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,4BAEC;IAED,yCAEC;IAED,mFAGC;IAED,mCAeC;IAED,+CAwBC;IAED,6CAIC;IAED,mCAsBC;IAED,+DA0BC;IAED,wHAgCC;IAED,kGA8BC;IAED,0EAGC;IAED,qFA4BC;IAED,0GAsBC;IAED,sEAGC;IAED,kEAeC;IAED,iFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED;;;;;;;;;;;;;MAeC;IAED,2EASC;IAED,qCAkBC;IAED,8DAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,wCAUC;IAED,sDAMC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAaC;IAED,kDAKC;IAED,iEAOC;IAED,+CAEC;IAED,8CAEC;IAED,+CAEC;IAED,4DAgBC;IAED,oBASC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAj/BD;IAQE,gFAKC;IAZD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|
package/script/midy-GMLite.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MidyGMLite = void 0;
|
|
4
4
|
const _esm_js_1 = require("./deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js");
|
|
5
|
-
const _esm_js_2 = require("./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.
|
|
5
|
+
const _esm_js_2 = require("./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js");
|
|
6
6
|
class Note {
|
|
7
7
|
constructor(noteNumber, velocity, startTime, instrumentKey) {
|
|
8
8
|
Object.defineProperty(this, "bufferSource", {
|
|
@@ -153,6 +153,7 @@ class MidyGMLite {
|
|
|
153
153
|
});
|
|
154
154
|
this.audioContext = audioContext;
|
|
155
155
|
this.masterGain = new GainNode(audioContext);
|
|
156
|
+
this.controlChangeHandlers = this.createControlChangeHandlers();
|
|
156
157
|
this.channels = this.createChannels(audioContext);
|
|
157
158
|
this.masterGain.connect(audioContext.destination);
|
|
158
159
|
this.GM1SystemOn();
|
|
@@ -167,12 +168,14 @@ class MidyGMLite {
|
|
|
167
168
|
addSoundFont(soundFont) {
|
|
168
169
|
const index = this.soundFonts.length;
|
|
169
170
|
this.soundFonts.push(soundFont);
|
|
170
|
-
soundFont.parsed.presetHeaders
|
|
171
|
+
const presetHeaders = soundFont.parsed.presetHeaders;
|
|
172
|
+
for (let i = 0; i < presetHeaders.length; i++) {
|
|
173
|
+
const presetHeader = presetHeaders[i];
|
|
171
174
|
if (!presetHeader.presetName.startsWith("\u0000")) { // TODO: Only SF3 generated by PolyPone?
|
|
172
175
|
const banks = this.soundFontTable[presetHeader.preset];
|
|
173
176
|
banks.set(presetHeader.bank, index);
|
|
174
177
|
}
|
|
175
|
-
}
|
|
178
|
+
}
|
|
176
179
|
}
|
|
177
180
|
async loadSoundFont(soundFontUrl) {
|
|
178
181
|
const response = await fetch(soundFontUrl);
|
|
@@ -217,27 +220,25 @@ class MidyGMLite {
|
|
|
217
220
|
return channels;
|
|
218
221
|
}
|
|
219
222
|
async createNoteBuffer(instrumentKey, isSF3) {
|
|
223
|
+
const sampleStart = instrumentKey.start;
|
|
220
224
|
const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
|
|
221
225
|
if (isSF3) {
|
|
222
|
-
const sample =
|
|
223
|
-
sample.set(instrumentKey.sample);
|
|
226
|
+
const sample = instrumentKey.sample.slice(sampleStart, sampleEnd);
|
|
224
227
|
const audioBuffer = await this.audioContext.decodeAudioData(sample.buffer);
|
|
225
|
-
for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
|
|
226
|
-
const channelData = audioBuffer.getChannelData(channel);
|
|
227
|
-
channelData.set(channelData.subarray(0, sampleEnd));
|
|
228
|
-
}
|
|
229
228
|
return audioBuffer;
|
|
230
229
|
}
|
|
231
230
|
else {
|
|
232
|
-
const sample = instrumentKey.sample.subarray(
|
|
233
|
-
const floatSample = this.convertToFloat32Array(sample);
|
|
231
|
+
const sample = instrumentKey.sample.subarray(sampleStart, sampleEnd);
|
|
234
232
|
const audioBuffer = new AudioBuffer({
|
|
235
233
|
numberOfChannels: 1,
|
|
236
234
|
length: sample.length,
|
|
237
235
|
sampleRate: instrumentKey.sampleRate,
|
|
238
236
|
});
|
|
239
237
|
const channelData = audioBuffer.getChannelData(0);
|
|
240
|
-
|
|
238
|
+
const int16Array = new Int16Array(sample.buffer);
|
|
239
|
+
for (let i = 0; i < int16Array.length; i++) {
|
|
240
|
+
channelData[i] = int16Array[i] / 32768;
|
|
241
|
+
}
|
|
241
242
|
return audioBuffer;
|
|
242
243
|
}
|
|
243
244
|
}
|
|
@@ -253,14 +254,6 @@ class MidyGMLite {
|
|
|
253
254
|
}
|
|
254
255
|
return bufferSource;
|
|
255
256
|
}
|
|
256
|
-
convertToFloat32Array(uint8Array) {
|
|
257
|
-
const int16Array = new Int16Array(uint8Array.buffer);
|
|
258
|
-
const float32Array = new Float32Array(int16Array.length);
|
|
259
|
-
for (let i = 0; i < int16Array.length; i++) {
|
|
260
|
-
float32Array[i] = int16Array[i] / 32768;
|
|
261
|
-
}
|
|
262
|
-
return float32Array;
|
|
263
|
-
}
|
|
264
257
|
async scheduleTimelineEvents(t, offset, queueIndex) {
|
|
265
258
|
while (queueIndex < this.timeline.length) {
|
|
266
259
|
const event = this.timeline[queueIndex];
|
|
@@ -371,9 +364,11 @@ class MidyGMLite {
|
|
|
371
364
|
bank: this.channels[i].bank,
|
|
372
365
|
};
|
|
373
366
|
}
|
|
374
|
-
midi.tracks.
|
|
367
|
+
for (let i = 0; i < midi.tracks.length; i++) {
|
|
368
|
+
const track = midi.tracks[i];
|
|
375
369
|
let currentTicks = 0;
|
|
376
|
-
track.
|
|
370
|
+
for (let j = 0; j < track.length; j++) {
|
|
371
|
+
const event = track[j];
|
|
377
372
|
currentTicks += event.deltaTime;
|
|
378
373
|
event.ticks = currentTicks;
|
|
379
374
|
switch (event.type) {
|
|
@@ -393,8 +388,8 @@ class MidyGMLite {
|
|
|
393
388
|
}
|
|
394
389
|
delete event.deltaTime;
|
|
395
390
|
timeline.push(event);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
398
393
|
const priority = {
|
|
399
394
|
controller: 0,
|
|
400
395
|
sysEx: 1,
|
|
@@ -419,7 +414,7 @@ class MidyGMLite {
|
|
|
419
414
|
}
|
|
420
415
|
return { instruments, timeline };
|
|
421
416
|
}
|
|
422
|
-
async stopChannelNotes(channelNumber, velocity,
|
|
417
|
+
async stopChannelNotes(channelNumber, velocity, force) {
|
|
423
418
|
const now = this.audioContext.currentTime;
|
|
424
419
|
const channel = this.channels[channelNumber];
|
|
425
420
|
channel.scheduledNotes.forEach((noteList) => {
|
|
@@ -427,16 +422,16 @@ class MidyGMLite {
|
|
|
427
422
|
const note = noteList[i];
|
|
428
423
|
if (!note)
|
|
429
424
|
continue;
|
|
430
|
-
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now,
|
|
425
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, force);
|
|
431
426
|
this.notePromises.push(promise);
|
|
432
427
|
}
|
|
433
428
|
});
|
|
434
429
|
channel.scheduledNotes.clear();
|
|
435
430
|
await Promise.all(this.notePromises);
|
|
436
431
|
}
|
|
437
|
-
stopNotes(velocity,
|
|
432
|
+
stopNotes(velocity, force) {
|
|
438
433
|
for (let i = 0; i < this.channels.length; i++) {
|
|
439
|
-
this.stopChannelNotes(i, velocity,
|
|
434
|
+
this.stopChannelNotes(i, velocity, force);
|
|
440
435
|
}
|
|
441
436
|
return Promise.all(this.notePromises);
|
|
442
437
|
}
|
|
@@ -612,7 +607,7 @@ class MidyGMLite {
|
|
|
612
607
|
note.volumeNode = new GainNode(this.audioContext);
|
|
613
608
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
614
609
|
type: "lowpass",
|
|
615
|
-
Q: instrumentKey.initialFilterQ / 10
|
|
610
|
+
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
616
611
|
});
|
|
617
612
|
this.setVolumeEnvelope(note);
|
|
618
613
|
this.setFilterEnvelope(note);
|
|
@@ -625,7 +620,7 @@ class MidyGMLite {
|
|
|
625
620
|
}
|
|
626
621
|
note.bufferSource.connect(note.filterNode);
|
|
627
622
|
note.filterNode.connect(note.volumeNode);
|
|
628
|
-
note.bufferSource.start(startTime
|
|
623
|
+
note.bufferSource.start(startTime);
|
|
629
624
|
return note;
|
|
630
625
|
}
|
|
631
626
|
async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
|
|
@@ -636,7 +631,7 @@ class MidyGMLite {
|
|
|
636
631
|
return;
|
|
637
632
|
const soundFont = this.soundFonts[soundFontIndex];
|
|
638
633
|
const isSF3 = soundFont.parsed.info.version.major === 3;
|
|
639
|
-
const instrumentKey = soundFont.getInstrumentKey(bankNumber, channel.program, noteNumber);
|
|
634
|
+
const instrumentKey = soundFont.getInstrumentKey(bankNumber, channel.program, noteNumber, velocity);
|
|
640
635
|
if (!instrumentKey)
|
|
641
636
|
return;
|
|
642
637
|
const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
|
|
@@ -654,9 +649,38 @@ class MidyGMLite {
|
|
|
654
649
|
const now = this.audioContext.currentTime;
|
|
655
650
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
656
651
|
}
|
|
657
|
-
|
|
652
|
+
stopNote(stopTime, endTime, scheduledNotes, index) {
|
|
653
|
+
const note = scheduledNotes[index];
|
|
654
|
+
note.volumeNode.gain
|
|
655
|
+
.cancelScheduledValues(stopTime)
|
|
656
|
+
.linearRampToValueAtTime(0, endTime);
|
|
657
|
+
note.ending = true;
|
|
658
|
+
this.scheduleTask(() => {
|
|
659
|
+
note.bufferSource.loop = false;
|
|
660
|
+
}, endTime);
|
|
661
|
+
return new Promise((resolve) => {
|
|
662
|
+
note.bufferSource.onended = () => {
|
|
663
|
+
scheduledNotes[index] = null;
|
|
664
|
+
note.bufferSource.disconnect();
|
|
665
|
+
note.volumeNode.disconnect();
|
|
666
|
+
note.filterNode.disconnect();
|
|
667
|
+
if (note.modulationDepth) {
|
|
668
|
+
note.volumeDepth.disconnect();
|
|
669
|
+
note.modulationDepth.disconnect();
|
|
670
|
+
note.modulationLFO.stop();
|
|
671
|
+
}
|
|
672
|
+
if (note.vibratoDepth) {
|
|
673
|
+
note.vibratoDepth.disconnect();
|
|
674
|
+
note.vibratoLFO.stop();
|
|
675
|
+
}
|
|
676
|
+
resolve();
|
|
677
|
+
};
|
|
678
|
+
note.bufferSource.stop(endTime);
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, force) {
|
|
658
682
|
const channel = this.channels[channelNumber];
|
|
659
|
-
if (
|
|
683
|
+
if (!force && channel.sustainPedal)
|
|
660
684
|
return;
|
|
661
685
|
if (!channel.scheduledNotes.has(noteNumber))
|
|
662
686
|
return;
|
|
@@ -668,33 +692,11 @@ class MidyGMLite {
|
|
|
668
692
|
if (note.ending)
|
|
669
693
|
continue;
|
|
670
694
|
const volEndTime = stopTime + note.instrumentKey.volRelease;
|
|
671
|
-
note.volumeNode.gain
|
|
672
|
-
.cancelScheduledValues(stopTime)
|
|
673
|
-
.linearRampToValueAtTime(0, volEndTime);
|
|
674
695
|
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
675
696
|
note.filterNode.frequency
|
|
676
697
|
.cancelScheduledValues(stopTime)
|
|
677
698
|
.linearRampToValueAtTime(0, modRelease);
|
|
678
|
-
|
|
679
|
-
this.scheduleTask(() => {
|
|
680
|
-
note.bufferSource.loop = false;
|
|
681
|
-
}, stopTime);
|
|
682
|
-
return new Promise((resolve) => {
|
|
683
|
-
note.bufferSource.onended = () => {
|
|
684
|
-
scheduledNotes[i] = null;
|
|
685
|
-
note.bufferSource.disconnect();
|
|
686
|
-
note.volumeNode.disconnect();
|
|
687
|
-
note.filterNode.disconnect();
|
|
688
|
-
if (note.volumeDepth)
|
|
689
|
-
note.volumeDepth.disconnect();
|
|
690
|
-
if (note.modulationDepth)
|
|
691
|
-
note.modulationDepth.disconnect();
|
|
692
|
-
if (note.modulationLFO)
|
|
693
|
-
note.modulationLFO.stop();
|
|
694
|
-
resolve();
|
|
695
|
-
};
|
|
696
|
-
note.bufferSource.stop(volEndTime);
|
|
697
|
-
});
|
|
699
|
+
this.stopNote(stopTime, volEndTime, scheduledNotes, i);
|
|
698
700
|
}
|
|
699
701
|
}
|
|
700
702
|
releaseNote(channelNumber, noteNumber, velocity) {
|
|
@@ -752,34 +754,29 @@ class MidyGMLite {
|
|
|
752
754
|
channel.pitchBendRange * 100;
|
|
753
755
|
this.updateDetune(channel, detuneChange);
|
|
754
756
|
}
|
|
757
|
+
createControlChangeHandlers() {
|
|
758
|
+
return {
|
|
759
|
+
1: this.setModulationDepth,
|
|
760
|
+
6: this.dataEntryMSB,
|
|
761
|
+
7: this.setVolume,
|
|
762
|
+
10: this.setPan,
|
|
763
|
+
11: this.setExpression,
|
|
764
|
+
38: this.dataEntryLSB,
|
|
765
|
+
64: this.setSustainPedal,
|
|
766
|
+
100: this.setRPNLSB,
|
|
767
|
+
101: this.setRPNMSB,
|
|
768
|
+
120: this.allSoundOff,
|
|
769
|
+
121: this.resetAllControllers,
|
|
770
|
+
123: this.allNotesOff,
|
|
771
|
+
};
|
|
772
|
+
}
|
|
755
773
|
handleControlChange(channelNumber, controller, value) {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
return this.setVolume(channelNumber, value);
|
|
763
|
-
case 10:
|
|
764
|
-
return this.setPan(channelNumber, value);
|
|
765
|
-
case 11:
|
|
766
|
-
return this.setExpression(channelNumber, value);
|
|
767
|
-
case 38:
|
|
768
|
-
return this.dataEntryLSB(channelNumber, value);
|
|
769
|
-
case 64:
|
|
770
|
-
return this.setSustainPedal(channelNumber, value);
|
|
771
|
-
case 100:
|
|
772
|
-
return this.setRPNLSB(channelNumber, value);
|
|
773
|
-
case 101:
|
|
774
|
-
return this.setRPNMSB(channelNumber, value);
|
|
775
|
-
case 120:
|
|
776
|
-
return this.allSoundOff(channelNumber);
|
|
777
|
-
case 121:
|
|
778
|
-
return this.resetAllControllers(channelNumber);
|
|
779
|
-
case 123:
|
|
780
|
-
return this.allNotesOff(channelNumber);
|
|
781
|
-
default:
|
|
782
|
-
console.warn(`Unsupported Control change: controller=${controller} value=${value}`);
|
|
774
|
+
const handler = this.controlChangeHandlers[controller];
|
|
775
|
+
if (handler) {
|
|
776
|
+
handler.call(this, channelNumber, value);
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
console.warn(`Unsupported Control change: controller=${controller} value=${value}`);
|
|
783
780
|
}
|
|
784
781
|
}
|
|
785
782
|
updateModulation(channel) {
|
|
@@ -808,7 +805,7 @@ class MidyGMLite {
|
|
|
808
805
|
setVolume(channelNumber, volume) {
|
|
809
806
|
const channel = this.channels[channelNumber];
|
|
810
807
|
channel.volume = volume / 127;
|
|
811
|
-
this.
|
|
808
|
+
this.updateChannelVolume(channel);
|
|
812
809
|
}
|
|
813
810
|
panToGain(pan) {
|
|
814
811
|
const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
|
|
@@ -820,18 +817,18 @@ class MidyGMLite {
|
|
|
820
817
|
setPan(channelNumber, pan) {
|
|
821
818
|
const channel = this.channels[channelNumber];
|
|
822
819
|
channel.pan = pan;
|
|
823
|
-
this.
|
|
820
|
+
this.updateChannelVolume(channel);
|
|
824
821
|
}
|
|
825
822
|
setExpression(channelNumber, expression) {
|
|
826
823
|
const channel = this.channels[channelNumber];
|
|
827
824
|
channel.expression = expression / 127;
|
|
828
|
-
this.
|
|
825
|
+
this.updateChannelVolume(channel);
|
|
829
826
|
}
|
|
830
827
|
dataEntryLSB(channelNumber, value) {
|
|
831
828
|
this.channels[channelNumber].dataLSB = value;
|
|
832
829
|
this.handleRPN(channelNumber);
|
|
833
830
|
}
|
|
834
|
-
|
|
831
|
+
updateChannelVolume(channel) {
|
|
835
832
|
const now = this.audioContext.currentTime;
|
|
836
833
|
const volume = channel.volume * channel.expression;
|
|
837
834
|
const { gainLeft, gainRight } = this.panToGain(channel.pan);
|
|
@@ -926,11 +923,12 @@ class MidyGMLite {
|
|
|
926
923
|
}
|
|
927
924
|
}
|
|
928
925
|
GM1SystemOn() {
|
|
929
|
-
this.channels.
|
|
926
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
927
|
+
const channel = this.channels[i];
|
|
930
928
|
channel.bankMSB = 0;
|
|
931
929
|
channel.bankLSB = 0;
|
|
932
930
|
channel.bank = 0;
|
|
933
|
-
}
|
|
931
|
+
}
|
|
934
932
|
this.channels[9].bankMSB = 1;
|
|
935
933
|
this.channels[9].bank = 128;
|
|
936
934
|
}
|
package/script/midy.d.ts
CHANGED
|
@@ -97,6 +97,42 @@ export class Midy {
|
|
|
97
97
|
};
|
|
98
98
|
};
|
|
99
99
|
masterGain: any;
|
|
100
|
+
controlChangeHandlers: {
|
|
101
|
+
0: (channelNumber: any, msb: any) => void;
|
|
102
|
+
1: (channelNumber: any, modulation: any) => void;
|
|
103
|
+
5: (channelNumber: any, portamentoTime: any) => void;
|
|
104
|
+
6: (channelNumber: any, value: any) => void;
|
|
105
|
+
7: (channelNumber: any, volume: any) => void;
|
|
106
|
+
10: (channelNumber: any, pan: any) => void;
|
|
107
|
+
11: (channelNumber: any, expression: any) => void;
|
|
108
|
+
32: (channelNumber: any, lsb: any) => void;
|
|
109
|
+
38: (channelNumber: any, value: any) => void;
|
|
110
|
+
64: (channelNumber: any, value: any) => void;
|
|
111
|
+
65: (channelNumber: any, value: any) => void;
|
|
112
|
+
66: (channelNumber: any, value: any) => void;
|
|
113
|
+
67: (channelNumber: any, softPedal: any) => void;
|
|
114
|
+
71: (channelNumber: any, filterResonance: any) => void;
|
|
115
|
+
72: (channelNumber: any, releaseTime: any) => void;
|
|
116
|
+
73: (channelNumber: any, attackTime: any) => void;
|
|
117
|
+
74: (channelNumber: any, brightness: any) => void;
|
|
118
|
+
75: (channelNumber: any, dacayTime: any) => void;
|
|
119
|
+
76: (channelNumber: any, vibratoRate: any) => void;
|
|
120
|
+
77: (channelNumber: any, vibratoDepth: any) => void;
|
|
121
|
+
78: (channelNumber: any, vibratoDelay: any) => void;
|
|
122
|
+
91: (channelNumber: any, reverbSendLevel: any) => void;
|
|
123
|
+
93: (channelNumber: any, chorusSendLevel: any) => void;
|
|
124
|
+
96: (channelNumber: any) => void;
|
|
125
|
+
97: (channelNumber: any) => void;
|
|
126
|
+
100: (channelNumber: any, value: any) => void;
|
|
127
|
+
101: (channelNumber: any, value: any) => void;
|
|
128
|
+
120: (channelNumber: any) => Promise<void>;
|
|
129
|
+
121: (channelNumber: any) => void;
|
|
130
|
+
123: (channelNumber: any) => Promise<void>;
|
|
131
|
+
124: () => void;
|
|
132
|
+
125: () => void;
|
|
133
|
+
126: () => void;
|
|
134
|
+
127: () => void;
|
|
135
|
+
};
|
|
100
136
|
channels: any[];
|
|
101
137
|
reverbEffect: {
|
|
102
138
|
input: any;
|
|
@@ -123,7 +159,7 @@ export class Midy {
|
|
|
123
159
|
createChannels(audioContext: any): any[];
|
|
124
160
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
125
161
|
createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
|
|
126
|
-
|
|
162
|
+
findPortamentoTarget(queueIndex: any): any;
|
|
127
163
|
scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
|
|
128
164
|
getQueueIndex(second: any): number;
|
|
129
165
|
playNotes(): Promise<any>;
|
|
@@ -133,8 +169,8 @@ export class Midy {
|
|
|
133
169
|
instruments: Set<any>;
|
|
134
170
|
timeline: any[];
|
|
135
171
|
};
|
|
136
|
-
stopChannelNotes(channelNumber: any, velocity: any,
|
|
137
|
-
stopNotes(velocity: any,
|
|
172
|
+
stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
|
|
173
|
+
stopNotes(velocity: any, force: any): Promise<any[]>;
|
|
138
174
|
start(): Promise<void>;
|
|
139
175
|
stop(): void;
|
|
140
176
|
pause(): void;
|
|
@@ -170,18 +206,21 @@ export class Midy {
|
|
|
170
206
|
centToHz(cent: any): number;
|
|
171
207
|
calcSemitoneOffset(channel: any): any;
|
|
172
208
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
209
|
+
setPortamentoStartVolumeEnvelope(channel: any, note: any): void;
|
|
173
210
|
setVolumeEnvelope(channel: any, note: any): void;
|
|
174
211
|
setPitch(note: any, semitoneOffset: any): void;
|
|
175
212
|
clampCutoffFrequency(frequency: any): number;
|
|
213
|
+
setPortamentoStartFilterEnvelope(channel: any, note: any): void;
|
|
176
214
|
setFilterEnvelope(channel: any, note: any): void;
|
|
177
215
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
178
216
|
startVibrato(channel: any, note: any, startTime: any): void;
|
|
179
|
-
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
217
|
+
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, portamento: any, isSF3: any): Promise<Note>;
|
|
180
218
|
calcBank(channel: any, channelNumber: any): any;
|
|
181
|
-
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
182
|
-
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
183
|
-
|
|
184
|
-
|
|
219
|
+
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
|
|
220
|
+
noteOn(channelNumber: any, noteNumber: any, velocity: any, portamento: any): Promise<void>;
|
|
221
|
+
stopNote(stopTime: any, endTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
222
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
|
|
223
|
+
releaseNote(channelNumber: any, noteNumber: any, velocity: any, portamentoNoteNumber: any): Promise<any> | undefined;
|
|
185
224
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
186
225
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
187
226
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
@@ -190,7 +229,43 @@ export class Midy {
|
|
|
190
229
|
handleChannelPressure(channelNumber: any, pressure: any): void;
|
|
191
230
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
192
231
|
setPitchBend(channelNumber: any, pitchBend: any): void;
|
|
193
|
-
|
|
232
|
+
createControlChangeHandlers(): {
|
|
233
|
+
0: (channelNumber: any, msb: any) => void;
|
|
234
|
+
1: (channelNumber: any, modulation: any) => void;
|
|
235
|
+
5: (channelNumber: any, portamentoTime: any) => void;
|
|
236
|
+
6: (channelNumber: any, value: any) => void;
|
|
237
|
+
7: (channelNumber: any, volume: any) => void;
|
|
238
|
+
10: (channelNumber: any, pan: any) => void;
|
|
239
|
+
11: (channelNumber: any, expression: any) => void;
|
|
240
|
+
32: (channelNumber: any, lsb: any) => void;
|
|
241
|
+
38: (channelNumber: any, value: any) => void;
|
|
242
|
+
64: (channelNumber: any, value: any) => void;
|
|
243
|
+
65: (channelNumber: any, value: any) => void;
|
|
244
|
+
66: (channelNumber: any, value: any) => void;
|
|
245
|
+
67: (channelNumber: any, softPedal: any) => void;
|
|
246
|
+
71: (channelNumber: any, filterResonance: any) => void;
|
|
247
|
+
72: (channelNumber: any, releaseTime: any) => void;
|
|
248
|
+
73: (channelNumber: any, attackTime: any) => void;
|
|
249
|
+
74: (channelNumber: any, brightness: any) => void;
|
|
250
|
+
75: (channelNumber: any, dacayTime: any) => void;
|
|
251
|
+
76: (channelNumber: any, vibratoRate: any) => void;
|
|
252
|
+
77: (channelNumber: any, vibratoDepth: any) => void;
|
|
253
|
+
78: (channelNumber: any, vibratoDelay: any) => void;
|
|
254
|
+
91: (channelNumber: any, reverbSendLevel: any) => void;
|
|
255
|
+
93: (channelNumber: any, chorusSendLevel: any) => void;
|
|
256
|
+
96: (channelNumber: any) => void;
|
|
257
|
+
97: (channelNumber: any) => void;
|
|
258
|
+
100: (channelNumber: any, value: any) => void;
|
|
259
|
+
101: (channelNumber: any, value: any) => void;
|
|
260
|
+
120: (channelNumber: any) => Promise<void>;
|
|
261
|
+
121: (channelNumber: any) => void;
|
|
262
|
+
123: (channelNumber: any) => Promise<void>;
|
|
263
|
+
124: () => void;
|
|
264
|
+
125: () => void;
|
|
265
|
+
126: () => void;
|
|
266
|
+
127: () => void;
|
|
267
|
+
};
|
|
268
|
+
handleControlChange(channelNumber: any, controller: any, value: any): void;
|
|
194
269
|
setBankMSB(channelNumber: any, msb: any): void;
|
|
195
270
|
updateModulation(channel: any): void;
|
|
196
271
|
setModulationDepth(channelNumber: any, modulation: any): void;
|
|
@@ -204,7 +279,7 @@ export class Midy {
|
|
|
204
279
|
setExpression(channelNumber: any, expression: any): void;
|
|
205
280
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
206
281
|
dataEntryLSB(channelNumber: any, value: any): void;
|
|
207
|
-
|
|
282
|
+
updateChannelVolume(channel: any): void;
|
|
208
283
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
209
284
|
setPortamento(channelNumber: any, value: any): void;
|
|
210
285
|
setReverbSendLevel(channelNumber: any, reverbSendLevel: 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":"AAwBA;IAkCE;;;;;;;;;;;;;;;;;;;;;;;;;MAyBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAgCF;;;;;
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
|