@marmooo/midy 0.1.5 → 0.1.7
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 +6 -5
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +97 -65
- package/esm/midy-GM2.d.ts +15 -9
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +316 -129
- package/esm/midy-GMLite.d.ts +6 -5
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +97 -65
- package/esm/midy.d.ts +15 -9
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +317 -134
- package/package.json +5 -1
- package/script/midy-GM1.d.ts +6 -5
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +100 -68
- package/script/midy-GM2.d.ts +15 -9
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +319 -132
- package/script/midy-GMLite.d.ts +6 -5
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +100 -68
- package/script/midy.d.ts +15 -9
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +320 -137
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts +0 -149
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +0 -1
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +0 -180
- package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts +0 -84
- package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts.map +0 -1
- package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js +0 -216
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts +0 -149
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +0 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +0 -190
- package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts +0 -84
- package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts.map +0 -1
- package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js +0 -221
package/esm/midy-GMLite.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export class MidyGMLite {
|
|
|
35
35
|
timeline: any[];
|
|
36
36
|
instruments: any[];
|
|
37
37
|
notePromises: any[];
|
|
38
|
+
exclusiveClassMap: Map<any, any>;
|
|
38
39
|
audioContext: any;
|
|
39
40
|
masterGain: any;
|
|
40
41
|
controlChangeHandlers: {
|
|
@@ -64,7 +65,6 @@ export class MidyGMLite {
|
|
|
64
65
|
createChannels(audioContext: any): any[];
|
|
65
66
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
66
67
|
createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
|
|
67
|
-
convertToFloat32Array(uint8Array: any): Float32Array;
|
|
68
68
|
scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
|
|
69
69
|
getQueueIndex(second: any): number;
|
|
70
70
|
playNotes(): Promise<any>;
|
|
@@ -74,8 +74,8 @@ export class MidyGMLite {
|
|
|
74
74
|
instruments: Set<any>;
|
|
75
75
|
timeline: any[];
|
|
76
76
|
};
|
|
77
|
-
stopChannelNotes(channelNumber: any, velocity: any,
|
|
78
|
-
stopNotes(velocity: any,
|
|
77
|
+
stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
|
|
78
|
+
stopNotes(velocity: any, force: any): Promise<any[]>;
|
|
79
79
|
start(): Promise<void>;
|
|
80
80
|
stop(): void;
|
|
81
81
|
pause(): void;
|
|
@@ -97,7 +97,8 @@ export class MidyGMLite {
|
|
|
97
97
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
98
98
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
99
99
|
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
100
|
-
|
|
100
|
+
stopNote(endTime: any, stopTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
101
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, force: any): Promise<any> | undefined;
|
|
101
102
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
102
103
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
103
104
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
@@ -129,7 +130,7 @@ export class MidyGMLite {
|
|
|
129
130
|
setPan(channelNumber: any, pan: any): void;
|
|
130
131
|
setExpression(channelNumber: any, expression: any): void;
|
|
131
132
|
dataEntryLSB(channelNumber: any, value: any): void;
|
|
132
|
-
|
|
133
|
+
updateChannelVolume(channel: any): void;
|
|
133
134
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
134
135
|
handleRPN(channelNumber: any): void;
|
|
135
136
|
setRPNMSB(channelNumber: any, value: 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":"
|
|
1
|
+
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAmBA;IAoBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAOC;IA9CD,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IAClB,iCAA8B;IAuB5B,kBAAgC;IAChC,gBAA4C;IAC5C;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,+DA2BC;IAED,mEAWC;IAED,2EA+CC;IAED,mCAOC;IAED,0BAkDC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgEC;IAED,+EAmBC;IAED,qDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,4BAEC;IAED,yCAEC;IAED,mFAGC;IAED,mCAeC;IAED,+CAwBC;IAED,6CAIC;IAED,mCAsBC;IAED,+DA0BC;IAED,wHAgCC;IAED,kGAgDC;IAED,0EAGC;IAED,qFA4BC;IAED,6HAuBC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;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;AA5gCD;IAQE,gFAKC;IAZD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|
package/esm/midy-GMLite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseMidi } from "
|
|
2
|
-
import { parse, SoundFont
|
|
1
|
+
import { parseMidi } from "midi-file";
|
|
2
|
+
import { parse, SoundFont } from "@marmooo/soundfont-parser";
|
|
3
3
|
class Note {
|
|
4
4
|
constructor(noteNumber, velocity, startTime, instrumentKey) {
|
|
5
5
|
Object.defineProperty(this, "bufferSource", {
|
|
@@ -148,6 +148,12 @@ export class MidyGMLite {
|
|
|
148
148
|
writable: true,
|
|
149
149
|
value: []
|
|
150
150
|
});
|
|
151
|
+
Object.defineProperty(this, "exclusiveClassMap", {
|
|
152
|
+
enumerable: true,
|
|
153
|
+
configurable: true,
|
|
154
|
+
writable: true,
|
|
155
|
+
value: new Map()
|
|
156
|
+
});
|
|
151
157
|
this.audioContext = audioContext;
|
|
152
158
|
this.masterGain = new GainNode(audioContext);
|
|
153
159
|
this.controlChangeHandlers = this.createControlChangeHandlers();
|
|
@@ -165,12 +171,14 @@ export class MidyGMLite {
|
|
|
165
171
|
addSoundFont(soundFont) {
|
|
166
172
|
const index = this.soundFonts.length;
|
|
167
173
|
this.soundFonts.push(soundFont);
|
|
168
|
-
soundFont.parsed.presetHeaders
|
|
174
|
+
const presetHeaders = soundFont.parsed.presetHeaders;
|
|
175
|
+
for (let i = 0; i < presetHeaders.length; i++) {
|
|
176
|
+
const presetHeader = presetHeaders[i];
|
|
169
177
|
if (!presetHeader.presetName.startsWith("\u0000")) { // TODO: Only SF3 generated by PolyPone?
|
|
170
178
|
const banks = this.soundFontTable[presetHeader.preset];
|
|
171
179
|
banks.set(presetHeader.bank, index);
|
|
172
180
|
}
|
|
173
|
-
}
|
|
181
|
+
}
|
|
174
182
|
}
|
|
175
183
|
async loadSoundFont(soundFontUrl) {
|
|
176
184
|
const response = await fetch(soundFontUrl);
|
|
@@ -215,27 +223,31 @@ export class MidyGMLite {
|
|
|
215
223
|
return channels;
|
|
216
224
|
}
|
|
217
225
|
async createNoteBuffer(instrumentKey, isSF3) {
|
|
226
|
+
const sampleStart = instrumentKey.start;
|
|
218
227
|
const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
|
|
219
228
|
if (isSF3) {
|
|
220
|
-
const sample =
|
|
221
|
-
sample.
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
channelData.set(channelData.subarray(0, sampleEnd));
|
|
226
|
-
}
|
|
229
|
+
const sample = instrumentKey.sample;
|
|
230
|
+
const start = sample.byteOffset + sampleStart;
|
|
231
|
+
const end = sample.byteOffset + sampleEnd;
|
|
232
|
+
const buffer = sample.buffer.slice(start, end);
|
|
233
|
+
const audioBuffer = await this.audioContext.decodeAudioData(buffer);
|
|
227
234
|
return audioBuffer;
|
|
228
235
|
}
|
|
229
236
|
else {
|
|
230
|
-
const sample = instrumentKey.sample
|
|
231
|
-
const
|
|
237
|
+
const sample = instrumentKey.sample;
|
|
238
|
+
const start = sample.byteOffset + sampleStart;
|
|
239
|
+
const end = sample.byteOffset + sampleEnd;
|
|
240
|
+
const buffer = sample.buffer.slice(start, end);
|
|
232
241
|
const audioBuffer = new AudioBuffer({
|
|
233
242
|
numberOfChannels: 1,
|
|
234
243
|
length: sample.length,
|
|
235
244
|
sampleRate: instrumentKey.sampleRate,
|
|
236
245
|
});
|
|
237
246
|
const channelData = audioBuffer.getChannelData(0);
|
|
238
|
-
|
|
247
|
+
const int16Array = new Int16Array(buffer);
|
|
248
|
+
for (let i = 0; i < int16Array.length; i++) {
|
|
249
|
+
channelData[i] = int16Array[i] / 32768;
|
|
250
|
+
}
|
|
239
251
|
return audioBuffer;
|
|
240
252
|
}
|
|
241
253
|
}
|
|
@@ -251,14 +263,6 @@ export class MidyGMLite {
|
|
|
251
263
|
}
|
|
252
264
|
return bufferSource;
|
|
253
265
|
}
|
|
254
|
-
convertToFloat32Array(uint8Array) {
|
|
255
|
-
const int16Array = new Int16Array(uint8Array.buffer);
|
|
256
|
-
const float32Array = new Float32Array(int16Array.length);
|
|
257
|
-
for (let i = 0; i < int16Array.length; i++) {
|
|
258
|
-
float32Array[i] = int16Array[i] / 32768;
|
|
259
|
-
}
|
|
260
|
-
return float32Array;
|
|
261
|
-
}
|
|
262
266
|
async scheduleTimelineEvents(t, offset, queueIndex) {
|
|
263
267
|
while (queueIndex < this.timeline.length) {
|
|
264
268
|
const event = this.timeline[queueIndex];
|
|
@@ -314,6 +318,7 @@ export class MidyGMLite {
|
|
|
314
318
|
if (queueIndex >= this.timeline.length) {
|
|
315
319
|
await Promise.all(this.notePromises);
|
|
316
320
|
this.notePromises = [];
|
|
321
|
+
this.exclusiveClassMap.clear();
|
|
317
322
|
resolve();
|
|
318
323
|
return;
|
|
319
324
|
}
|
|
@@ -329,6 +334,7 @@ export class MidyGMLite {
|
|
|
329
334
|
}
|
|
330
335
|
else if (this.isStopping) {
|
|
331
336
|
await this.stopNotes(0, true);
|
|
337
|
+
this.exclusiveClassMap.clear();
|
|
332
338
|
this.notePromises = [];
|
|
333
339
|
resolve();
|
|
334
340
|
this.isStopping = false;
|
|
@@ -337,6 +343,7 @@ export class MidyGMLite {
|
|
|
337
343
|
}
|
|
338
344
|
else if (this.isSeeking) {
|
|
339
345
|
this.stopNotes(0, true);
|
|
346
|
+
this.exclusiveClassMap.clear();
|
|
340
347
|
this.startTime = this.audioContext.currentTime;
|
|
341
348
|
queueIndex = this.getQueueIndex(this.resumeTime);
|
|
342
349
|
offset = this.resumeTime - this.startTime;
|
|
@@ -369,9 +376,11 @@ export class MidyGMLite {
|
|
|
369
376
|
bank: this.channels[i].bank,
|
|
370
377
|
};
|
|
371
378
|
}
|
|
372
|
-
midi.tracks.
|
|
379
|
+
for (let i = 0; i < midi.tracks.length; i++) {
|
|
380
|
+
const track = midi.tracks[i];
|
|
373
381
|
let currentTicks = 0;
|
|
374
|
-
track.
|
|
382
|
+
for (let j = 0; j < track.length; j++) {
|
|
383
|
+
const event = track[j];
|
|
375
384
|
currentTicks += event.deltaTime;
|
|
376
385
|
event.ticks = currentTicks;
|
|
377
386
|
switch (event.type) {
|
|
@@ -391,8 +400,8 @@ export class MidyGMLite {
|
|
|
391
400
|
}
|
|
392
401
|
delete event.deltaTime;
|
|
393
402
|
timeline.push(event);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
396
405
|
const priority = {
|
|
397
406
|
controller: 0,
|
|
398
407
|
sysEx: 1,
|
|
@@ -417,7 +426,7 @@ export class MidyGMLite {
|
|
|
417
426
|
}
|
|
418
427
|
return { instruments, timeline };
|
|
419
428
|
}
|
|
420
|
-
async stopChannelNotes(channelNumber, velocity,
|
|
429
|
+
async stopChannelNotes(channelNumber, velocity, force) {
|
|
421
430
|
const now = this.audioContext.currentTime;
|
|
422
431
|
const channel = this.channels[channelNumber];
|
|
423
432
|
channel.scheduledNotes.forEach((noteList) => {
|
|
@@ -425,16 +434,16 @@ export class MidyGMLite {
|
|
|
425
434
|
const note = noteList[i];
|
|
426
435
|
if (!note)
|
|
427
436
|
continue;
|
|
428
|
-
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now,
|
|
437
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, force);
|
|
429
438
|
this.notePromises.push(promise);
|
|
430
439
|
}
|
|
431
440
|
});
|
|
432
441
|
channel.scheduledNotes.clear();
|
|
433
442
|
await Promise.all(this.notePromises);
|
|
434
443
|
}
|
|
435
|
-
stopNotes(velocity,
|
|
444
|
+
stopNotes(velocity, force) {
|
|
436
445
|
for (let i = 0; i < this.channels.length; i++) {
|
|
437
|
-
this.stopChannelNotes(i, velocity,
|
|
446
|
+
this.stopChannelNotes(i, velocity, force);
|
|
438
447
|
}
|
|
439
448
|
return Promise.all(this.notePromises);
|
|
440
449
|
}
|
|
@@ -610,7 +619,7 @@ export class MidyGMLite {
|
|
|
610
619
|
note.volumeNode = new GainNode(this.audioContext);
|
|
611
620
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
612
621
|
type: "lowpass",
|
|
613
|
-
Q: instrumentKey.initialFilterQ / 10
|
|
622
|
+
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
614
623
|
});
|
|
615
624
|
this.setVolumeEnvelope(note);
|
|
616
625
|
this.setFilterEnvelope(note);
|
|
@@ -623,7 +632,7 @@ export class MidyGMLite {
|
|
|
623
632
|
}
|
|
624
633
|
note.bufferSource.connect(note.filterNode);
|
|
625
634
|
note.filterNode.connect(note.volumeNode);
|
|
626
|
-
note.bufferSource.start(startTime
|
|
635
|
+
note.bufferSource.start(startTime);
|
|
627
636
|
return note;
|
|
628
637
|
}
|
|
629
638
|
async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
|
|
@@ -640,6 +649,19 @@ export class MidyGMLite {
|
|
|
640
649
|
const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
|
|
641
650
|
note.volumeNode.connect(channel.gainL);
|
|
642
651
|
note.volumeNode.connect(channel.gainR);
|
|
652
|
+
const exclusiveClass = instrumentKey.exclusiveClass;
|
|
653
|
+
if (exclusiveClass !== 0) {
|
|
654
|
+
if (this.exclusiveClassMap.has(exclusiveClass)) {
|
|
655
|
+
const prevEntry = this.exclusiveClassMap.get(exclusiveClass);
|
|
656
|
+
const [prevNote, prevChannelNumber] = prevEntry;
|
|
657
|
+
if (!prevNote.ending) {
|
|
658
|
+
this.scheduleNoteRelease(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
|
|
659
|
+
startTime, undefined, // portamentoNoteNumber
|
|
660
|
+
true);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
this.exclusiveClassMap.set(exclusiveClass, [note, channelNumber]);
|
|
664
|
+
}
|
|
643
665
|
const scheduledNotes = channel.scheduledNotes;
|
|
644
666
|
if (scheduledNotes.has(noteNumber)) {
|
|
645
667
|
scheduledNotes.get(noteNumber).push(note);
|
|
@@ -652,9 +674,38 @@ export class MidyGMLite {
|
|
|
652
674
|
const now = this.audioContext.currentTime;
|
|
653
675
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
654
676
|
}
|
|
655
|
-
|
|
677
|
+
stopNote(endTime, stopTime, scheduledNotes, index) {
|
|
678
|
+
const note = scheduledNotes[index];
|
|
679
|
+
note.volumeNode.gain
|
|
680
|
+
.cancelScheduledValues(endTime)
|
|
681
|
+
.linearRampToValueAtTime(0, stopTime);
|
|
682
|
+
note.ending = true;
|
|
683
|
+
this.scheduleTask(() => {
|
|
684
|
+
note.bufferSource.loop = false;
|
|
685
|
+
}, stopTime);
|
|
686
|
+
return new Promise((resolve) => {
|
|
687
|
+
note.bufferSource.onended = () => {
|
|
688
|
+
scheduledNotes[index] = null;
|
|
689
|
+
note.bufferSource.disconnect();
|
|
690
|
+
note.volumeNode.disconnect();
|
|
691
|
+
note.filterNode.disconnect();
|
|
692
|
+
if (note.modulationDepth) {
|
|
693
|
+
note.volumeDepth.disconnect();
|
|
694
|
+
note.modulationDepth.disconnect();
|
|
695
|
+
note.modulationLFO.stop();
|
|
696
|
+
}
|
|
697
|
+
if (note.vibratoDepth) {
|
|
698
|
+
note.vibratoDepth.disconnect();
|
|
699
|
+
note.vibratoLFO.stop();
|
|
700
|
+
}
|
|
701
|
+
resolve();
|
|
702
|
+
};
|
|
703
|
+
note.bufferSource.stop(stopTime);
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, endTime, force) {
|
|
656
707
|
const channel = this.channels[channelNumber];
|
|
657
|
-
if (
|
|
708
|
+
if (!force && channel.sustainPedal)
|
|
658
709
|
return;
|
|
659
710
|
if (!channel.scheduledNotes.has(noteNumber))
|
|
660
711
|
return;
|
|
@@ -665,33 +716,13 @@ export class MidyGMLite {
|
|
|
665
716
|
continue;
|
|
666
717
|
if (note.ending)
|
|
667
718
|
continue;
|
|
668
|
-
const
|
|
669
|
-
note.
|
|
670
|
-
.cancelScheduledValues(stopTime)
|
|
671
|
-
.linearRampToValueAtTime(0, volEndTime);
|
|
672
|
-
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
719
|
+
const volRelease = endTime + note.instrumentKey.volRelease;
|
|
720
|
+
const modRelease = endTime + note.instrumentKey.modRelease;
|
|
673
721
|
note.filterNode.frequency
|
|
674
|
-
.cancelScheduledValues(
|
|
722
|
+
.cancelScheduledValues(endTime)
|
|
675
723
|
.linearRampToValueAtTime(0, modRelease);
|
|
676
|
-
|
|
677
|
-
this.
|
|
678
|
-
note.bufferSource.loop = false;
|
|
679
|
-
}, stopTime);
|
|
680
|
-
return new Promise((resolve) => {
|
|
681
|
-
note.bufferSource.onended = () => {
|
|
682
|
-
scheduledNotes[i] = null;
|
|
683
|
-
note.bufferSource.disconnect();
|
|
684
|
-
note.volumeNode.disconnect();
|
|
685
|
-
note.filterNode.disconnect();
|
|
686
|
-
if (note.modulationDepth) {
|
|
687
|
-
note.volumeDepth.disconnect();
|
|
688
|
-
note.modulationDepth.disconnect();
|
|
689
|
-
note.modulationLFO.stop();
|
|
690
|
-
}
|
|
691
|
-
resolve();
|
|
692
|
-
};
|
|
693
|
-
note.bufferSource.stop(volEndTime);
|
|
694
|
-
});
|
|
724
|
+
const stopTime = Math.min(volRelease, modRelease);
|
|
725
|
+
return this.stopNote(endTime, stopTime, scheduledNotes, i);
|
|
695
726
|
}
|
|
696
727
|
}
|
|
697
728
|
releaseNote(channelNumber, noteNumber, velocity) {
|
|
@@ -800,7 +831,7 @@ export class MidyGMLite {
|
|
|
800
831
|
setVolume(channelNumber, volume) {
|
|
801
832
|
const channel = this.channels[channelNumber];
|
|
802
833
|
channel.volume = volume / 127;
|
|
803
|
-
this.
|
|
834
|
+
this.updateChannelVolume(channel);
|
|
804
835
|
}
|
|
805
836
|
panToGain(pan) {
|
|
806
837
|
const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
|
|
@@ -812,18 +843,18 @@ export class MidyGMLite {
|
|
|
812
843
|
setPan(channelNumber, pan) {
|
|
813
844
|
const channel = this.channels[channelNumber];
|
|
814
845
|
channel.pan = pan;
|
|
815
|
-
this.
|
|
846
|
+
this.updateChannelVolume(channel);
|
|
816
847
|
}
|
|
817
848
|
setExpression(channelNumber, expression) {
|
|
818
849
|
const channel = this.channels[channelNumber];
|
|
819
850
|
channel.expression = expression / 127;
|
|
820
|
-
this.
|
|
851
|
+
this.updateChannelVolume(channel);
|
|
821
852
|
}
|
|
822
853
|
dataEntryLSB(channelNumber, value) {
|
|
823
854
|
this.channels[channelNumber].dataLSB = value;
|
|
824
855
|
this.handleRPN(channelNumber);
|
|
825
856
|
}
|
|
826
|
-
|
|
857
|
+
updateChannelVolume(channel) {
|
|
827
858
|
const now = this.audioContext.currentTime;
|
|
828
859
|
const volume = channel.volume * channel.expression;
|
|
829
860
|
const { gainLeft, gainRight } = this.panToGain(channel.pan);
|
|
@@ -918,11 +949,12 @@ export class MidyGMLite {
|
|
|
918
949
|
}
|
|
919
950
|
}
|
|
920
951
|
GM1SystemOn() {
|
|
921
|
-
this.channels.
|
|
952
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
953
|
+
const channel = this.channels[i];
|
|
922
954
|
channel.bankMSB = 0;
|
|
923
955
|
channel.bankLSB = 0;
|
|
924
956
|
channel.bank = 0;
|
|
925
|
-
}
|
|
957
|
+
}
|
|
926
958
|
this.channels[9].bankMSB = 1;
|
|
927
959
|
this.channels[9].bank = 128;
|
|
928
960
|
}
|
package/esm/midy.d.ts
CHANGED
|
@@ -83,6 +83,7 @@ export class Midy {
|
|
|
83
83
|
timeline: any[];
|
|
84
84
|
instruments: any[];
|
|
85
85
|
notePromises: any[];
|
|
86
|
+
exclusiveClassMap: Map<any, any>;
|
|
86
87
|
defaultOptions: {
|
|
87
88
|
reverbAlgorithm: (audioContext: any) => {
|
|
88
89
|
input: any;
|
|
@@ -159,7 +160,7 @@ export class Midy {
|
|
|
159
160
|
createChannels(audioContext: any): any[];
|
|
160
161
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
161
162
|
createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
|
|
162
|
-
|
|
163
|
+
findPortamentoTarget(queueIndex: any): any;
|
|
163
164
|
scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
|
|
164
165
|
getQueueIndex(second: any): number;
|
|
165
166
|
playNotes(): Promise<any>;
|
|
@@ -169,8 +170,8 @@ export class Midy {
|
|
|
169
170
|
instruments: Set<any>;
|
|
170
171
|
timeline: any[];
|
|
171
172
|
};
|
|
172
|
-
stopChannelNotes(channelNumber: any, velocity: any,
|
|
173
|
-
stopNotes(velocity: any,
|
|
173
|
+
stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
|
|
174
|
+
stopNotes(velocity: any, force: any): Promise<any[]>;
|
|
174
175
|
start(): Promise<void>;
|
|
175
176
|
stop(): void;
|
|
176
177
|
pause(): void;
|
|
@@ -206,18 +207,21 @@ export class Midy {
|
|
|
206
207
|
centToHz(cent: any): number;
|
|
207
208
|
calcSemitoneOffset(channel: any): any;
|
|
208
209
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
210
|
+
setPortamentoStartVolumeEnvelope(channel: any, note: any): void;
|
|
209
211
|
setVolumeEnvelope(channel: any, note: any): void;
|
|
210
212
|
setPitch(note: any, semitoneOffset: any): void;
|
|
211
213
|
clampCutoffFrequency(frequency: any): number;
|
|
214
|
+
setPortamentoStartFilterEnvelope(channel: any, note: any): void;
|
|
212
215
|
setFilterEnvelope(channel: any, note: any): void;
|
|
213
216
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
214
217
|
startVibrato(channel: any, note: any, startTime: any): void;
|
|
215
|
-
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
218
|
+
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, portamento: any, isSF3: any): Promise<Note>;
|
|
216
219
|
calcBank(channel: any, channelNumber: any): any;
|
|
217
|
-
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
218
|
-
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
219
|
-
|
|
220
|
-
|
|
220
|
+
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
|
|
221
|
+
noteOn(channelNumber: any, noteNumber: any, velocity: any, portamento: any): Promise<void>;
|
|
222
|
+
stopNote(endTime: any, stopTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
223
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
|
|
224
|
+
releaseNote(channelNumber: any, noteNumber: any, velocity: any, portamentoNoteNumber: any): Promise<any> | undefined;
|
|
221
225
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
222
226
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
223
227
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
@@ -276,7 +280,7 @@ export class Midy {
|
|
|
276
280
|
setExpression(channelNumber: any, expression: any): void;
|
|
277
281
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
278
282
|
dataEntryLSB(channelNumber: any, value: any): void;
|
|
279
|
-
|
|
283
|
+
updateChannelVolume(channel: any): void;
|
|
280
284
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
281
285
|
setPortamento(channelNumber: any, value: any): void;
|
|
282
286
|
setReverbSendLevel(channelNumber: any, reverbSendLevel: any): void;
|
|
@@ -357,6 +361,8 @@ declare class Note {
|
|
|
357
361
|
modulationDepth: any;
|
|
358
362
|
vibratoLFO: any;
|
|
359
363
|
vibratoDepth: any;
|
|
364
|
+
reverbEffectsSend: any;
|
|
365
|
+
chorusEffectsSend: any;
|
|
360
366
|
noteNumber: any;
|
|
361
367
|
velocity: any;
|
|
362
368
|
startTime: any;
|
package/esm/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
|