@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-GM1.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export class MidyGM1 {
|
|
|
37
37
|
timeline: any[];
|
|
38
38
|
instruments: any[];
|
|
39
39
|
notePromises: any[];
|
|
40
|
+
exclusiveClassMap: Map<any, any>;
|
|
40
41
|
audioContext: any;
|
|
41
42
|
masterGain: any;
|
|
42
43
|
controlChangeHandlers: {
|
|
@@ -66,7 +67,6 @@ export class MidyGM1 {
|
|
|
66
67
|
createChannels(audioContext: any): any[];
|
|
67
68
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
68
69
|
createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
|
|
69
|
-
convertToFloat32Array(uint8Array: any): Float32Array;
|
|
70
70
|
scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
|
|
71
71
|
getQueueIndex(second: any): number;
|
|
72
72
|
playNotes(): Promise<any>;
|
|
@@ -76,8 +76,8 @@ export class MidyGM1 {
|
|
|
76
76
|
instruments: Set<any>;
|
|
77
77
|
timeline: any[];
|
|
78
78
|
};
|
|
79
|
-
stopChannelNotes(channelNumber: any, velocity: any,
|
|
80
|
-
stopNotes(velocity: any,
|
|
79
|
+
stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
|
|
80
|
+
stopNotes(velocity: any, force: any): Promise<any[]>;
|
|
81
81
|
start(): Promise<void>;
|
|
82
82
|
stop(): void;
|
|
83
83
|
pause(): void;
|
|
@@ -99,7 +99,8 @@ export class MidyGM1 {
|
|
|
99
99
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
100
100
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
101
101
|
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
102
|
-
|
|
102
|
+
stopNote(endTime: any, stopTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
103
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, force: any): Promise<any> | undefined;
|
|
103
104
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
104
105
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
105
106
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
@@ -131,7 +132,7 @@ export class MidyGM1 {
|
|
|
131
132
|
setPan(channelNumber: any, pan: any): void;
|
|
132
133
|
setExpression(channelNumber: any, expression: any): void;
|
|
133
134
|
dataEntryLSB(channelNumber: any, value: any): void;
|
|
134
|
-
|
|
135
|
+
updateChannelVolume(channel: any): void;
|
|
135
136
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
136
137
|
limitData(channel: any, minMSB: any, maxMSB: any, minLSB: any, maxLSB: any): void;
|
|
137
138
|
limitDataMSB(channel: any, minMSB: any, maxMSB: 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":"
|
|
1
|
+
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqBA;IAoBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAOC;IAhDD,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;IAyB5B,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,sCAGC;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,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAaC;IAED,kDAKC;IAED,iEAOC;IAED,8CAKC;IAED,yDAMC;IAED,gDAKC;IAED,6DAMC;IAED,+CAEC;IAED,8CAEC;IAED,+CAEC;IAED,4DAgBC;IAED,oBASC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AA9kCD;IAUE,gFAKC;IAdD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAChB,gBAAW;IACX,kBAAa;IAGX,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|
package/esm/midy-GM1.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", {
|
|
@@ -160,6 +160,12 @@ export class MidyGM1 {
|
|
|
160
160
|
writable: true,
|
|
161
161
|
value: []
|
|
162
162
|
});
|
|
163
|
+
Object.defineProperty(this, "exclusiveClassMap", {
|
|
164
|
+
enumerable: true,
|
|
165
|
+
configurable: true,
|
|
166
|
+
writable: true,
|
|
167
|
+
value: new Map()
|
|
168
|
+
});
|
|
163
169
|
this.audioContext = audioContext;
|
|
164
170
|
this.masterGain = new GainNode(audioContext);
|
|
165
171
|
this.controlChangeHandlers = this.createControlChangeHandlers();
|
|
@@ -177,12 +183,14 @@ export class MidyGM1 {
|
|
|
177
183
|
addSoundFont(soundFont) {
|
|
178
184
|
const index = this.soundFonts.length;
|
|
179
185
|
this.soundFonts.push(soundFont);
|
|
180
|
-
soundFont.parsed.presetHeaders
|
|
186
|
+
const presetHeaders = soundFont.parsed.presetHeaders;
|
|
187
|
+
for (let i = 0; i < presetHeaders.length; i++) {
|
|
188
|
+
const presetHeader = presetHeaders[i];
|
|
181
189
|
if (!presetHeader.presetName.startsWith("\u0000")) { // TODO: Only SF3 generated by PolyPone?
|
|
182
190
|
const banks = this.soundFontTable[presetHeader.preset];
|
|
183
191
|
banks.set(presetHeader.bank, index);
|
|
184
192
|
}
|
|
185
|
-
}
|
|
193
|
+
}
|
|
186
194
|
}
|
|
187
195
|
async loadSoundFont(soundFontUrl) {
|
|
188
196
|
const response = await fetch(soundFontUrl);
|
|
@@ -227,27 +235,31 @@ export class MidyGM1 {
|
|
|
227
235
|
return channels;
|
|
228
236
|
}
|
|
229
237
|
async createNoteBuffer(instrumentKey, isSF3) {
|
|
238
|
+
const sampleStart = instrumentKey.start;
|
|
230
239
|
const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
|
|
231
240
|
if (isSF3) {
|
|
232
|
-
const sample =
|
|
233
|
-
sample.
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
channelData.set(channelData.subarray(0, sampleEnd));
|
|
238
|
-
}
|
|
241
|
+
const sample = instrumentKey.sample;
|
|
242
|
+
const start = sample.byteOffset + sampleStart;
|
|
243
|
+
const end = sample.byteOffset + sampleEnd;
|
|
244
|
+
const buffer = sample.buffer.slice(start, end);
|
|
245
|
+
const audioBuffer = await this.audioContext.decodeAudioData(buffer);
|
|
239
246
|
return audioBuffer;
|
|
240
247
|
}
|
|
241
248
|
else {
|
|
242
|
-
const sample = instrumentKey.sample
|
|
243
|
-
const
|
|
249
|
+
const sample = instrumentKey.sample;
|
|
250
|
+
const start = sample.byteOffset + sampleStart;
|
|
251
|
+
const end = sample.byteOffset + sampleEnd;
|
|
252
|
+
const buffer = sample.buffer.slice(start, end);
|
|
244
253
|
const audioBuffer = new AudioBuffer({
|
|
245
254
|
numberOfChannels: 1,
|
|
246
255
|
length: sample.length,
|
|
247
256
|
sampleRate: instrumentKey.sampleRate,
|
|
248
257
|
});
|
|
249
258
|
const channelData = audioBuffer.getChannelData(0);
|
|
250
|
-
|
|
259
|
+
const int16Array = new Int16Array(buffer);
|
|
260
|
+
for (let i = 0; i < int16Array.length; i++) {
|
|
261
|
+
channelData[i] = int16Array[i] / 32768;
|
|
262
|
+
}
|
|
251
263
|
return audioBuffer;
|
|
252
264
|
}
|
|
253
265
|
}
|
|
@@ -263,14 +275,6 @@ export class MidyGM1 {
|
|
|
263
275
|
}
|
|
264
276
|
return bufferSource;
|
|
265
277
|
}
|
|
266
|
-
convertToFloat32Array(uint8Array) {
|
|
267
|
-
const int16Array = new Int16Array(uint8Array.buffer);
|
|
268
|
-
const float32Array = new Float32Array(int16Array.length);
|
|
269
|
-
for (let i = 0; i < int16Array.length; i++) {
|
|
270
|
-
float32Array[i] = int16Array[i] / 32768;
|
|
271
|
-
}
|
|
272
|
-
return float32Array;
|
|
273
|
-
}
|
|
274
278
|
async scheduleTimelineEvents(t, offset, queueIndex) {
|
|
275
279
|
while (queueIndex < this.timeline.length) {
|
|
276
280
|
const event = this.timeline[queueIndex];
|
|
@@ -326,6 +330,7 @@ export class MidyGM1 {
|
|
|
326
330
|
if (queueIndex >= this.timeline.length) {
|
|
327
331
|
await Promise.all(this.notePromises);
|
|
328
332
|
this.notePromises = [];
|
|
333
|
+
this.exclusiveClassMap.clear();
|
|
329
334
|
resolve();
|
|
330
335
|
return;
|
|
331
336
|
}
|
|
@@ -341,6 +346,7 @@ export class MidyGM1 {
|
|
|
341
346
|
}
|
|
342
347
|
else if (this.isStopping) {
|
|
343
348
|
await this.stopNotes(0, true);
|
|
349
|
+
this.exclusiveClassMap.clear();
|
|
344
350
|
this.notePromises = [];
|
|
345
351
|
resolve();
|
|
346
352
|
this.isStopping = false;
|
|
@@ -349,6 +355,7 @@ export class MidyGM1 {
|
|
|
349
355
|
}
|
|
350
356
|
else if (this.isSeeking) {
|
|
351
357
|
this.stopNotes(0, true);
|
|
358
|
+
this.exclusiveClassMap.clear();
|
|
352
359
|
this.startTime = this.audioContext.currentTime;
|
|
353
360
|
queueIndex = this.getQueueIndex(this.resumeTime);
|
|
354
361
|
offset = this.resumeTime - this.startTime;
|
|
@@ -381,9 +388,11 @@ export class MidyGM1 {
|
|
|
381
388
|
bank: this.channels[i].bank,
|
|
382
389
|
};
|
|
383
390
|
}
|
|
384
|
-
midi.tracks.
|
|
391
|
+
for (let i = 0; i < midi.tracks.length; i++) {
|
|
392
|
+
const track = midi.tracks[i];
|
|
385
393
|
let currentTicks = 0;
|
|
386
|
-
track.
|
|
394
|
+
for (let j = 0; j < track.length; j++) {
|
|
395
|
+
const event = track[j];
|
|
387
396
|
currentTicks += event.deltaTime;
|
|
388
397
|
event.ticks = currentTicks;
|
|
389
398
|
switch (event.type) {
|
|
@@ -403,8 +412,8 @@ export class MidyGM1 {
|
|
|
403
412
|
}
|
|
404
413
|
delete event.deltaTime;
|
|
405
414
|
timeline.push(event);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
408
417
|
const priority = {
|
|
409
418
|
controller: 0,
|
|
410
419
|
sysEx: 1,
|
|
@@ -429,7 +438,7 @@ export class MidyGM1 {
|
|
|
429
438
|
}
|
|
430
439
|
return { instruments, timeline };
|
|
431
440
|
}
|
|
432
|
-
async stopChannelNotes(channelNumber, velocity,
|
|
441
|
+
async stopChannelNotes(channelNumber, velocity, force) {
|
|
433
442
|
const now = this.audioContext.currentTime;
|
|
434
443
|
const channel = this.channels[channelNumber];
|
|
435
444
|
channel.scheduledNotes.forEach((noteList) => {
|
|
@@ -437,16 +446,16 @@ export class MidyGM1 {
|
|
|
437
446
|
const note = noteList[i];
|
|
438
447
|
if (!note)
|
|
439
448
|
continue;
|
|
440
|
-
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now,
|
|
449
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, force);
|
|
441
450
|
this.notePromises.push(promise);
|
|
442
451
|
}
|
|
443
452
|
});
|
|
444
453
|
channel.scheduledNotes.clear();
|
|
445
454
|
await Promise.all(this.notePromises);
|
|
446
455
|
}
|
|
447
|
-
stopNotes(velocity,
|
|
456
|
+
stopNotes(velocity, force) {
|
|
448
457
|
for (let i = 0; i < this.channels.length; i++) {
|
|
449
|
-
this.stopChannelNotes(i, velocity,
|
|
458
|
+
this.stopChannelNotes(i, velocity, force);
|
|
450
459
|
}
|
|
451
460
|
return Promise.all(this.notePromises);
|
|
452
461
|
}
|
|
@@ -623,7 +632,7 @@ export class MidyGM1 {
|
|
|
623
632
|
note.volumeNode = new GainNode(this.audioContext);
|
|
624
633
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
625
634
|
type: "lowpass",
|
|
626
|
-
Q: instrumentKey.initialFilterQ / 10
|
|
635
|
+
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
627
636
|
});
|
|
628
637
|
this.setVolumeEnvelope(note);
|
|
629
638
|
this.setFilterEnvelope(note);
|
|
@@ -636,7 +645,7 @@ export class MidyGM1 {
|
|
|
636
645
|
}
|
|
637
646
|
note.bufferSource.connect(note.filterNode);
|
|
638
647
|
note.filterNode.connect(note.volumeNode);
|
|
639
|
-
note.bufferSource.start(startTime
|
|
648
|
+
note.bufferSource.start(startTime);
|
|
640
649
|
return note;
|
|
641
650
|
}
|
|
642
651
|
async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
|
|
@@ -653,6 +662,19 @@ export class MidyGM1 {
|
|
|
653
662
|
const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
|
|
654
663
|
note.volumeNode.connect(channel.gainL);
|
|
655
664
|
note.volumeNode.connect(channel.gainR);
|
|
665
|
+
const exclusiveClass = instrumentKey.exclusiveClass;
|
|
666
|
+
if (exclusiveClass !== 0) {
|
|
667
|
+
if (this.exclusiveClassMap.has(exclusiveClass)) {
|
|
668
|
+
const prevEntry = this.exclusiveClassMap.get(exclusiveClass);
|
|
669
|
+
const [prevNote, prevChannelNumber] = prevEntry;
|
|
670
|
+
if (!prevNote.ending) {
|
|
671
|
+
this.scheduleNoteRelease(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
|
|
672
|
+
startTime, undefined, // portamentoNoteNumber
|
|
673
|
+
true);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
this.exclusiveClassMap.set(exclusiveClass, [note, channelNumber]);
|
|
677
|
+
}
|
|
656
678
|
const scheduledNotes = channel.scheduledNotes;
|
|
657
679
|
if (scheduledNotes.has(noteNumber)) {
|
|
658
680
|
scheduledNotes.get(noteNumber).push(note);
|
|
@@ -665,9 +687,38 @@ export class MidyGM1 {
|
|
|
665
687
|
const now = this.audioContext.currentTime;
|
|
666
688
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
667
689
|
}
|
|
668
|
-
|
|
690
|
+
stopNote(endTime, stopTime, scheduledNotes, index) {
|
|
691
|
+
const note = scheduledNotes[index];
|
|
692
|
+
note.volumeNode.gain
|
|
693
|
+
.cancelScheduledValues(endTime)
|
|
694
|
+
.linearRampToValueAtTime(0, stopTime);
|
|
695
|
+
note.ending = true;
|
|
696
|
+
this.scheduleTask(() => {
|
|
697
|
+
note.bufferSource.loop = false;
|
|
698
|
+
}, stopTime);
|
|
699
|
+
return new Promise((resolve) => {
|
|
700
|
+
note.bufferSource.onended = () => {
|
|
701
|
+
scheduledNotes[index] = null;
|
|
702
|
+
note.bufferSource.disconnect();
|
|
703
|
+
note.volumeNode.disconnect();
|
|
704
|
+
note.filterNode.disconnect();
|
|
705
|
+
if (note.modulationDepth) {
|
|
706
|
+
note.volumeDepth.disconnect();
|
|
707
|
+
note.modulationDepth.disconnect();
|
|
708
|
+
note.modulationLFO.stop();
|
|
709
|
+
}
|
|
710
|
+
if (note.vibratoDepth) {
|
|
711
|
+
note.vibratoDepth.disconnect();
|
|
712
|
+
note.vibratoLFO.stop();
|
|
713
|
+
}
|
|
714
|
+
resolve();
|
|
715
|
+
};
|
|
716
|
+
note.bufferSource.stop(stopTime);
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, endTime, force) {
|
|
669
720
|
const channel = this.channels[channelNumber];
|
|
670
|
-
if (
|
|
721
|
+
if (!force && channel.sustainPedal)
|
|
671
722
|
return;
|
|
672
723
|
if (!channel.scheduledNotes.has(noteNumber))
|
|
673
724
|
return;
|
|
@@ -678,33 +729,13 @@ export class MidyGM1 {
|
|
|
678
729
|
continue;
|
|
679
730
|
if (note.ending)
|
|
680
731
|
continue;
|
|
681
|
-
const
|
|
682
|
-
note.
|
|
683
|
-
.cancelScheduledValues(stopTime)
|
|
684
|
-
.linearRampToValueAtTime(0, volEndTime);
|
|
685
|
-
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
732
|
+
const volRelease = endTime + note.instrumentKey.volRelease;
|
|
733
|
+
const modRelease = endTime + note.instrumentKey.modRelease;
|
|
686
734
|
note.filterNode.frequency
|
|
687
|
-
.cancelScheduledValues(
|
|
735
|
+
.cancelScheduledValues(endTime)
|
|
688
736
|
.linearRampToValueAtTime(0, modRelease);
|
|
689
|
-
|
|
690
|
-
this.
|
|
691
|
-
note.bufferSource.loop = false;
|
|
692
|
-
}, stopTime);
|
|
693
|
-
return new Promise((resolve) => {
|
|
694
|
-
note.bufferSource.onended = () => {
|
|
695
|
-
scheduledNotes[i] = null;
|
|
696
|
-
note.bufferSource.disconnect();
|
|
697
|
-
note.volumeNode.disconnect();
|
|
698
|
-
note.filterNode.disconnect();
|
|
699
|
-
if (note.modulationDepth) {
|
|
700
|
-
note.volumeDepth.disconnect();
|
|
701
|
-
note.modulationDepth.disconnect();
|
|
702
|
-
note.modulationLFO.stop();
|
|
703
|
-
}
|
|
704
|
-
resolve();
|
|
705
|
-
};
|
|
706
|
-
note.bufferSource.stop(volEndTime);
|
|
707
|
-
});
|
|
737
|
+
const stopTime = Math.min(volRelease, modRelease);
|
|
738
|
+
return this.stopNote(endTime, stopTime, scheduledNotes, i);
|
|
708
739
|
}
|
|
709
740
|
}
|
|
710
741
|
releaseNote(channelNumber, noteNumber, velocity) {
|
|
@@ -813,7 +844,7 @@ export class MidyGM1 {
|
|
|
813
844
|
setVolume(channelNumber, volume) {
|
|
814
845
|
const channel = this.channels[channelNumber];
|
|
815
846
|
channel.volume = volume / 127;
|
|
816
|
-
this.
|
|
847
|
+
this.updateChannelVolume(channel);
|
|
817
848
|
}
|
|
818
849
|
panToGain(pan) {
|
|
819
850
|
const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
|
|
@@ -825,18 +856,18 @@ export class MidyGM1 {
|
|
|
825
856
|
setPan(channelNumber, pan) {
|
|
826
857
|
const channel = this.channels[channelNumber];
|
|
827
858
|
channel.pan = pan;
|
|
828
|
-
this.
|
|
859
|
+
this.updateChannelVolume(channel);
|
|
829
860
|
}
|
|
830
861
|
setExpression(channelNumber, expression) {
|
|
831
862
|
const channel = this.channels[channelNumber];
|
|
832
863
|
channel.expression = expression / 127;
|
|
833
|
-
this.
|
|
864
|
+
this.updateChannelVolume(channel);
|
|
834
865
|
}
|
|
835
866
|
dataEntryLSB(channelNumber, value) {
|
|
836
867
|
this.channels[channelNumber].dataLSB = value;
|
|
837
868
|
this.handleRPN(channelNumber, 0);
|
|
838
869
|
}
|
|
839
|
-
|
|
870
|
+
updateChannelVolume(channel) {
|
|
840
871
|
const now = this.audioContext.currentTime;
|
|
841
872
|
const volume = channel.volume * channel.expression;
|
|
842
873
|
const { gainLeft, gainRight } = this.panToGain(channel.pan);
|
|
@@ -989,11 +1020,12 @@ export class MidyGM1 {
|
|
|
989
1020
|
}
|
|
990
1021
|
}
|
|
991
1022
|
GM1SystemOn() {
|
|
992
|
-
this.channels.
|
|
1023
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1024
|
+
const channel = this.channels[i];
|
|
993
1025
|
channel.bankMSB = 0;
|
|
994
1026
|
channel.bankLSB = 0;
|
|
995
1027
|
channel.bank = 0;
|
|
996
|
-
}
|
|
1028
|
+
}
|
|
997
1029
|
this.channels[9].bankMSB = 1;
|
|
998
1030
|
this.channels[9].bank = 128;
|
|
999
1031
|
}
|
package/esm/midy-GM2.d.ts
CHANGED
|
@@ -78,6 +78,7 @@ export class MidyGM2 {
|
|
|
78
78
|
timeline: any[];
|
|
79
79
|
instruments: any[];
|
|
80
80
|
notePromises: any[];
|
|
81
|
+
exclusiveClassMap: Map<any, any>;
|
|
81
82
|
defaultOptions: {
|
|
82
83
|
reverbAlgorithm: (audioContext: any) => {
|
|
83
84
|
input: any;
|
|
@@ -144,7 +145,7 @@ export class MidyGM2 {
|
|
|
144
145
|
createChannels(audioContext: any): any[];
|
|
145
146
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
146
147
|
createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
|
|
147
|
-
|
|
148
|
+
findPortamentoTarget(queueIndex: any): any;
|
|
148
149
|
scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
|
|
149
150
|
getQueueIndex(second: any): number;
|
|
150
151
|
playNotes(): Promise<any>;
|
|
@@ -154,8 +155,8 @@ export class MidyGM2 {
|
|
|
154
155
|
instruments: Set<any>;
|
|
155
156
|
timeline: any[];
|
|
156
157
|
};
|
|
157
|
-
stopChannelNotes(channelNumber: any, velocity: any,
|
|
158
|
-
stopNotes(velocity: any,
|
|
158
|
+
stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
|
|
159
|
+
stopNotes(velocity: any, force: any): Promise<any[]>;
|
|
159
160
|
start(): Promise<void>;
|
|
160
161
|
stop(): void;
|
|
161
162
|
pause(): void;
|
|
@@ -191,18 +192,21 @@ export class MidyGM2 {
|
|
|
191
192
|
centToHz(cent: any): number;
|
|
192
193
|
calcSemitoneOffset(channel: any): any;
|
|
193
194
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
195
|
+
setPortamentoStartVolumeEnvelope(channel: any, note: any): void;
|
|
194
196
|
setVolumeEnvelope(note: any): void;
|
|
195
197
|
setPitch(note: any, semitoneOffset: any): void;
|
|
196
198
|
clampCutoffFrequency(frequency: any): number;
|
|
199
|
+
setPortamentoStartFilterEnvelope(channel: any, note: any): void;
|
|
197
200
|
setFilterEnvelope(channel: any, note: any): void;
|
|
198
201
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
199
202
|
startVibrato(channel: any, note: any, startTime: any): void;
|
|
200
|
-
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
203
|
+
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, portamento: any, isSF3: any): Promise<Note>;
|
|
201
204
|
calcBank(channel: any, channelNumber: any): any;
|
|
202
|
-
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
203
|
-
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
204
|
-
|
|
205
|
-
|
|
205
|
+
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
|
|
206
|
+
noteOn(channelNumber: any, noteNumber: any, velocity: any, portamento: any): Promise<void>;
|
|
207
|
+
stopNote(endTime: any, stopTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
208
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
|
|
209
|
+
releaseNote(channelNumber: any, noteNumber: any, velocity: any, portamentoNoteNumber: any): Promise<any> | undefined;
|
|
206
210
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
207
211
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
208
212
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
@@ -250,7 +254,7 @@ export class MidyGM2 {
|
|
|
250
254
|
setExpression(channelNumber: any, expression: any): void;
|
|
251
255
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
252
256
|
dataEntryLSB(channelNumber: any, value: any): void;
|
|
253
|
-
|
|
257
|
+
updateChannelVolume(channel: any): void;
|
|
254
258
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
255
259
|
setPortamento(channelNumber: any, value: any): void;
|
|
256
260
|
setReverbSendLevel(channelNumber: any, reverbSendLevel: any): void;
|
|
@@ -321,6 +325,8 @@ declare class Note {
|
|
|
321
325
|
modulationDepth: any;
|
|
322
326
|
vibratoLFO: any;
|
|
323
327
|
vibratoDepth: any;
|
|
328
|
+
reverbEffectsSend: any;
|
|
329
|
+
chorusEffectsSend: any;
|
|
324
330
|
noteNumber: any;
|
|
325
331
|
velocity: any;
|
|
326
332
|
startTime: any;
|
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":"
|
|
1
|
+
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}
|