@marmooo/midy 0.3.8 → 0.4.0
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 -24
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +98 -51
- package/esm/midy-GM2.d.ts +6 -29
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +107 -60
- package/esm/midy-GMLite.d.ts +6 -24
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +100 -53
- package/esm/midy.d.ts +6 -30
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +107 -60
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +6 -24
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +98 -51
- package/script/midy-GM2.d.ts +6 -29
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +107 -60
- package/script/midy-GMLite.d.ts +6 -24
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +100 -53
- package/script/midy.d.ts +6 -30
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +107 -60
package/esm/midy-GM1.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export class MidyGM1 {
|
|
|
25
25
|
soundFontTable: never[][];
|
|
26
26
|
voiceCounter: Map<any, any>;
|
|
27
27
|
voiceCache: Map<any, any>;
|
|
28
|
+
realtimeVoiceCache: Map<any, any>;
|
|
28
29
|
isPlaying: boolean;
|
|
29
30
|
isPausing: boolean;
|
|
30
31
|
isPaused: boolean;
|
|
@@ -104,17 +105,16 @@ export class MidyGM1 {
|
|
|
104
105
|
clampCutoffFrequency(frequency: any): number;
|
|
105
106
|
setFilterEnvelope(note: any, scheduleTime: any): void;
|
|
106
107
|
startModulation(channel: any, note: any, scheduleTime: any): void;
|
|
107
|
-
getAudioBuffer(channel: any, noteNumber: any, velocity: any, voiceParams: any): Promise<any>;
|
|
108
|
-
|
|
108
|
+
getAudioBuffer(channel: any, noteNumber: any, velocity: any, voiceParams: any, realtime: any): Promise<any>;
|
|
109
|
+
setNoteAudioNode(channel: any, note: any, realtime: any): Promise<any>;
|
|
109
110
|
handleExclusiveClass(note: any, channelNumber: any, startTime: any): void;
|
|
110
|
-
|
|
111
|
-
noteOn(channelNumber: any, noteNumber: any, velocity: any,
|
|
111
|
+
setNoteRouting(channelNumber: any, note: any, startTime: any): void;
|
|
112
|
+
noteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
112
113
|
disconnectNote(note: any): void;
|
|
113
114
|
releaseNote(channel: any, note: any, endTime: any): Promise<any>;
|
|
114
|
-
|
|
115
|
+
noteOff(channelNumber: any, noteNumber: any, velocity: any, endTime: any, force: any): void;
|
|
115
116
|
setNoteIndex(channel: any, index: any): void;
|
|
116
117
|
findNoteOffIndex(channel: any, noteNumber: any): any;
|
|
117
|
-
noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): void;
|
|
118
118
|
releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
|
|
119
119
|
createMessageHandlers(): any[];
|
|
120
120
|
handleMessage(data: any, scheduleTime: any): void;
|
|
@@ -179,22 +179,4 @@ export class MidyGM1 {
|
|
|
179
179
|
handleSysEx(data: any, scheduleTime: any): void;
|
|
180
180
|
scheduleTask(callback: any, scheduleTime: any): Promise<any>;
|
|
181
181
|
}
|
|
182
|
-
declare class Note {
|
|
183
|
-
constructor(noteNumber: any, velocity: any, startTime: any, voice: any, voiceParams: any);
|
|
184
|
-
index: number;
|
|
185
|
-
ending: boolean;
|
|
186
|
-
bufferSource: any;
|
|
187
|
-
filterNode: any;
|
|
188
|
-
filterDepth: any;
|
|
189
|
-
volumeEnvelopeNode: any;
|
|
190
|
-
volumeDepth: any;
|
|
191
|
-
modulationLFO: any;
|
|
192
|
-
modulationDepth: any;
|
|
193
|
-
noteNumber: any;
|
|
194
|
-
velocity: any;
|
|
195
|
-
startTime: any;
|
|
196
|
-
voice: any;
|
|
197
|
-
voiceParams: any;
|
|
198
|
-
}
|
|
199
|
-
export {};
|
|
200
182
|
//# sourceMappingURL=midy-GM1.d.ts.map
|
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":"AA6FA;IA0BE;;;;;;;;;;;MAWE;IAEF,+BAeC;IArDD,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAgBnC,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IAMnD,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAWC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDAUC;IAED,4DASC;IAED,yEAqDC;IAED,mCAOC;IAED,uBASC;IAED,yDA2BC;IAED,2BAwCC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAKC;IAED,uBAQC;IAED,wBAKC;IAED,0BAKC;IAED,wBAOC;IAED,sBAIC;IAED,yDAQC;IAED,yEASC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDAsBC;IAED,kEAoBC;IAED,4GAkCC;IAED,uEAmCC;IAED,0EAiBC;IAED,oEASC;IAED,0FAwBC;IAED,gCASC;IAED,iEAqBC;IAED,4FAmBC;IAED,6CAUC;IAED,qDAUC;IAED,sFAeC;IAED,+BAmBC;IAED,kDAOC;IAED,uGA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAWC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MAiCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDASC;IAED,iFAKC;IAED,oEAKC;IAED;;;MAMC;IAED,8DAKC;IAED,4EAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,2DAMC;IAED,uDAkBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,iEAMC;IAED,uEAQC;IAED,mEAKC;IAED,yEAQC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCASC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
|
package/esm/midy-GM1.js
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { parseMidi } from "midi-file";
|
|
2
2
|
import { parse, SoundFont } from "@marmooo/soundfont-parser";
|
|
3
3
|
class Note {
|
|
4
|
-
constructor(noteNumber, velocity, startTime
|
|
4
|
+
constructor(noteNumber, velocity, startTime) {
|
|
5
|
+
Object.defineProperty(this, "voice", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(this, "voiceParams", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: void 0
|
|
16
|
+
});
|
|
5
17
|
Object.defineProperty(this, "index", {
|
|
6
18
|
enumerable: true,
|
|
7
19
|
configurable: true,
|
|
@@ -14,6 +26,12 @@ class Note {
|
|
|
14
26
|
writable: true,
|
|
15
27
|
value: false
|
|
16
28
|
});
|
|
29
|
+
Object.defineProperty(this, "pending", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: true
|
|
34
|
+
});
|
|
17
35
|
Object.defineProperty(this, "bufferSource", {
|
|
18
36
|
enumerable: true,
|
|
19
37
|
configurable: true,
|
|
@@ -59,8 +77,6 @@ class Note {
|
|
|
59
77
|
this.noteNumber = noteNumber;
|
|
60
78
|
this.velocity = velocity;
|
|
61
79
|
this.startTime = startTime;
|
|
62
|
-
this.voice = voice;
|
|
63
|
-
this.voiceParams = voiceParams;
|
|
64
80
|
}
|
|
65
81
|
}
|
|
66
82
|
// normalized to 0-1 for use with the SF2 modulator model
|
|
@@ -214,6 +230,12 @@ export class MidyGM1 {
|
|
|
214
230
|
writable: true,
|
|
215
231
|
value: new Map()
|
|
216
232
|
});
|
|
233
|
+
Object.defineProperty(this, "realtimeVoiceCache", {
|
|
234
|
+
enumerable: true,
|
|
235
|
+
configurable: true,
|
|
236
|
+
writable: true,
|
|
237
|
+
value: new Map()
|
|
238
|
+
});
|
|
217
239
|
Object.defineProperty(this, "isPlaying", {
|
|
218
240
|
enumerable: true,
|
|
219
241
|
configurable: true,
|
|
@@ -444,10 +466,10 @@ export class MidyGM1 {
|
|
|
444
466
|
const startTime = event.startTime + schedulingOffset;
|
|
445
467
|
switch (event.type) {
|
|
446
468
|
case "noteOn":
|
|
447
|
-
await this.
|
|
469
|
+
await this.noteOn(event.channel, event.noteNumber, event.velocity, startTime);
|
|
448
470
|
break;
|
|
449
471
|
case "noteOff": {
|
|
450
|
-
const notePromise = this.
|
|
472
|
+
const notePromise = this.noteOff(event.channel, event.noteNumber, event.velocity, startTime, false);
|
|
451
473
|
if (notePromise)
|
|
452
474
|
this.notePromises.push(notePromise);
|
|
453
475
|
break;
|
|
@@ -480,6 +502,7 @@ export class MidyGM1 {
|
|
|
480
502
|
this.exclusiveClassNotes.fill(undefined);
|
|
481
503
|
this.drumExclusiveClassNotes.fill(undefined);
|
|
482
504
|
this.voiceCache.clear();
|
|
505
|
+
this.realtimeVoiceCache.clear();
|
|
483
506
|
for (let i = 0; i < this.channels.length; i++) {
|
|
484
507
|
this.channels[i].scheduledNotes = [];
|
|
485
508
|
this.resetChannelStates(i);
|
|
@@ -517,7 +540,6 @@ export class MidyGM1 {
|
|
|
517
540
|
this.notePromises = [];
|
|
518
541
|
while (queueIndex < this.timeline.length) {
|
|
519
542
|
const now = this.audioContext.currentTime;
|
|
520
|
-
queueIndex = await this.scheduleTimelineEvents(now, queueIndex);
|
|
521
543
|
if (this.isPausing) {
|
|
522
544
|
await this.stopNotes(0, true, now);
|
|
523
545
|
await this.audioContext.suspend();
|
|
@@ -539,6 +561,7 @@ export class MidyGM1 {
|
|
|
539
561
|
this.isSeeking = false;
|
|
540
562
|
continue;
|
|
541
563
|
}
|
|
564
|
+
queueIndex = await this.scheduleTimelineEvents(now, queueIndex);
|
|
542
565
|
const waitTime = now + this.noteCheckInterval;
|
|
543
566
|
await this.scheduleTask(() => { }, waitTime);
|
|
544
567
|
}
|
|
@@ -616,7 +639,7 @@ export class MidyGM1 {
|
|
|
616
639
|
const channel = this.channels[channelNumber];
|
|
617
640
|
const promises = [];
|
|
618
641
|
this.processActiveNotes(channel, scheduleTime, (note) => {
|
|
619
|
-
const promise = this.
|
|
642
|
+
const promise = this.noteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force);
|
|
620
643
|
this.notePromises.push(promise);
|
|
621
644
|
promises.push(promise);
|
|
622
645
|
});
|
|
@@ -626,7 +649,7 @@ export class MidyGM1 {
|
|
|
626
649
|
const channel = this.channels[channelNumber];
|
|
627
650
|
const promises = [];
|
|
628
651
|
this.processScheduledNotes(channel, (note) => {
|
|
629
|
-
const promise = this.
|
|
652
|
+
const promise = this.noteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force);
|
|
630
653
|
this.notePromises.push(promise);
|
|
631
654
|
promises.push(promise);
|
|
632
655
|
});
|
|
@@ -659,7 +682,7 @@ export class MidyGM1 {
|
|
|
659
682
|
if (!this.isPlaying || this.isPaused)
|
|
660
683
|
return;
|
|
661
684
|
const now = this.audioContext.currentTime;
|
|
662
|
-
this.resumeTime
|
|
685
|
+
this.resumeTime = now - this.startTime - this.startDelay;
|
|
663
686
|
this.isPausing = true;
|
|
664
687
|
await this.playPromise;
|
|
665
688
|
this.isPausing = false;
|
|
@@ -685,11 +708,13 @@ export class MidyGM1 {
|
|
|
685
708
|
if (totalTime < event.startTime)
|
|
686
709
|
totalTime = event.startTime;
|
|
687
710
|
}
|
|
688
|
-
return totalTime;
|
|
711
|
+
return totalTime + this.startDelay;
|
|
689
712
|
}
|
|
690
713
|
currentTime() {
|
|
714
|
+
if (!this.isPlaying)
|
|
715
|
+
return this.resumeTime;
|
|
691
716
|
const now = this.audioContext.currentTime;
|
|
692
|
-
return
|
|
717
|
+
return now + this.resumeTime - this.startTime;
|
|
693
718
|
}
|
|
694
719
|
processScheduledNotes(channel, callback) {
|
|
695
720
|
const scheduledNotes = channel.scheduledNotes;
|
|
@@ -828,31 +853,42 @@ export class MidyGM1 {
|
|
|
828
853
|
note.modulationLFO.connect(note.volumeDepth);
|
|
829
854
|
note.volumeDepth.connect(note.volumeEnvelopeNode.gain);
|
|
830
855
|
}
|
|
831
|
-
async getAudioBuffer(channel, noteNumber, velocity, voiceParams) {
|
|
856
|
+
async getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime) {
|
|
832
857
|
const audioBufferId = this.getVoiceId(channel, noteNumber, velocity);
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
this.voiceCache.delete(audioBufferId);
|
|
838
|
-
}
|
|
839
|
-
return cache.audioBuffer;
|
|
840
|
-
}
|
|
841
|
-
else {
|
|
842
|
-
const maxCount = this.voiceCounter.get(audioBufferId) ?? 0;
|
|
858
|
+
if (realtime) {
|
|
859
|
+
const cachedAudioBuffer = this.realtimeVoiceCache.get(audioBufferId);
|
|
860
|
+
if (cachedAudioBuffer)
|
|
861
|
+
return cachedAudioBuffer;
|
|
843
862
|
const audioBuffer = await this.createAudioBuffer(voiceParams);
|
|
844
|
-
|
|
845
|
-
this.voiceCache.set(audioBufferId, cache);
|
|
863
|
+
this.realtimeVoiceCache.set(audioBufferId, audioBuffer);
|
|
846
864
|
return audioBuffer;
|
|
847
865
|
}
|
|
866
|
+
else {
|
|
867
|
+
const cache = this.voiceCache.get(audioBufferId);
|
|
868
|
+
if (cache) {
|
|
869
|
+
cache.counter += 1;
|
|
870
|
+
if (cache.maxCount <= cache.counter) {
|
|
871
|
+
this.voiceCache.delete(audioBufferId);
|
|
872
|
+
}
|
|
873
|
+
return cache.audioBuffer;
|
|
874
|
+
}
|
|
875
|
+
else {
|
|
876
|
+
const maxCount = this.voiceCounter.get(audioBufferId) ?? 0;
|
|
877
|
+
const audioBuffer = await this.createAudioBuffer(voiceParams);
|
|
878
|
+
const cache = { audioBuffer, maxCount, counter: 1 };
|
|
879
|
+
this.voiceCache.set(audioBufferId, cache);
|
|
880
|
+
return audioBuffer;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
848
883
|
}
|
|
849
|
-
async
|
|
884
|
+
async setNoteAudioNode(channel, note, realtime) {
|
|
850
885
|
const now = this.audioContext.currentTime;
|
|
886
|
+
const { noteNumber, velocity, startTime } = note;
|
|
851
887
|
const state = channel.state;
|
|
852
888
|
const controllerState = this.getControllerState(channel, noteNumber, velocity);
|
|
853
|
-
const voiceParams = voice.getAllParams(controllerState);
|
|
854
|
-
|
|
855
|
-
const audioBuffer = await this.getAudioBuffer(channel, noteNumber, velocity, voiceParams);
|
|
889
|
+
const voiceParams = note.voice.getAllParams(controllerState);
|
|
890
|
+
note.voiceParams = voiceParams;
|
|
891
|
+
const audioBuffer = await this.getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime);
|
|
856
892
|
note.bufferSource = this.createBufferSource(voiceParams, audioBuffer);
|
|
857
893
|
note.volumeEnvelopeNode = new GainNode(this.audioContext);
|
|
858
894
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
@@ -879,14 +915,31 @@ export class MidyGM1 {
|
|
|
879
915
|
if (prev) {
|
|
880
916
|
const [prevNote, prevChannelNumber] = prev;
|
|
881
917
|
if (prevNote && !prevNote.ending) {
|
|
882
|
-
this.
|
|
918
|
+
this.noteOff(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
|
|
883
919
|
startTime, true);
|
|
884
920
|
}
|
|
885
921
|
}
|
|
886
922
|
this.exclusiveClassNotes[exclusiveClass] = [note, channelNumber];
|
|
887
923
|
}
|
|
888
|
-
|
|
924
|
+
setNoteRouting(channelNumber, note, startTime) {
|
|
889
925
|
const channel = this.channels[channelNumber];
|
|
926
|
+
const volumeEnvelopeNode = note.volumeEnvelopeNode;
|
|
927
|
+
volumeEnvelopeNode.connect(channel.gainL);
|
|
928
|
+
volumeEnvelopeNode.connect(channel.gainR);
|
|
929
|
+
if (0.5 <= channel.state.sustainPedal) {
|
|
930
|
+
channel.sustainNotes.push(note);
|
|
931
|
+
}
|
|
932
|
+
this.handleExclusiveClass(note, channelNumber, startTime);
|
|
933
|
+
}
|
|
934
|
+
async noteOn(channelNumber, noteNumber, velocity, startTime) {
|
|
935
|
+
const channel = this.channels[channelNumber];
|
|
936
|
+
const realtime = startTime === undefined;
|
|
937
|
+
if (realtime)
|
|
938
|
+
startTime = this.audioContext.currentTime;
|
|
939
|
+
const note = new Note(noteNumber, velocity, startTime);
|
|
940
|
+
const scheduledNotes = channel.scheduledNotes;
|
|
941
|
+
note.index = scheduledNotes.length;
|
|
942
|
+
scheduledNotes.push(note);
|
|
890
943
|
const programNumber = channel.programNumber;
|
|
891
944
|
const bankTable = this.soundFontTable[programNumber];
|
|
892
945
|
if (!bankTable)
|
|
@@ -896,23 +949,16 @@ export class MidyGM1 {
|
|
|
896
949
|
if (soundFontIndex === undefined)
|
|
897
950
|
return;
|
|
898
951
|
const soundFont = this.soundFonts[soundFontIndex];
|
|
899
|
-
|
|
900
|
-
if (!voice)
|
|
952
|
+
note.voice = soundFont.getVoice(bank, programNumber, noteNumber, velocity);
|
|
953
|
+
if (!note.voice)
|
|
901
954
|
return;
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
note.
|
|
905
|
-
|
|
906
|
-
|
|
955
|
+
await this.setNoteAudioNode(channel, note, realtime);
|
|
956
|
+
this.setNoteRouting(channelNumber, note, startTime);
|
|
957
|
+
note.pending = false;
|
|
958
|
+
const off = note.offEvent;
|
|
959
|
+
if (off) {
|
|
960
|
+
this.noteOff(channelNumber, noteNumber, off.velocity, off.startTime);
|
|
907
961
|
}
|
|
908
|
-
this.handleExclusiveClass(note, channelNumber, startTime);
|
|
909
|
-
const scheduledNotes = channel.scheduledNotes;
|
|
910
|
-
note.index = scheduledNotes.length;
|
|
911
|
-
scheduledNotes.push(note);
|
|
912
|
-
}
|
|
913
|
-
noteOn(channelNumber, noteNumber, velocity, scheduleTime) {
|
|
914
|
-
scheduleTime ??= this.audioContext.currentTime;
|
|
915
|
-
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, scheduleTime, undefined);
|
|
916
962
|
}
|
|
917
963
|
disconnectNote(note) {
|
|
918
964
|
note.bufferSource.disconnect();
|
|
@@ -925,6 +971,7 @@ export class MidyGM1 {
|
|
|
925
971
|
}
|
|
926
972
|
}
|
|
927
973
|
releaseNote(channel, note, endTime) {
|
|
974
|
+
endTime ??= this.audioContext.currentTime;
|
|
928
975
|
const volRelease = endTime + note.voiceParams.volRelease;
|
|
929
976
|
const modRelease = endTime + note.voiceParams.modRelease;
|
|
930
977
|
const stopTime = Math.min(volRelease, modRelease);
|
|
@@ -945,7 +992,7 @@ export class MidyGM1 {
|
|
|
945
992
|
}, stopTime);
|
|
946
993
|
});
|
|
947
994
|
}
|
|
948
|
-
|
|
995
|
+
noteOff(channelNumber, noteNumber, velocity, endTime, force) {
|
|
949
996
|
const channel = this.channels[channelNumber];
|
|
950
997
|
if (!force && 0.5 <= channel.state.sustainPedal)
|
|
951
998
|
return;
|
|
@@ -953,6 +1000,10 @@ export class MidyGM1 {
|
|
|
953
1000
|
if (index < 0)
|
|
954
1001
|
return;
|
|
955
1002
|
const note = channel.scheduledNotes[index];
|
|
1003
|
+
if (note.pending) {
|
|
1004
|
+
note.offEvent = { velocity, startTime: endTime };
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
956
1007
|
note.ending = true;
|
|
957
1008
|
this.setNoteIndex(channel, index);
|
|
958
1009
|
this.releaseNote(channel, note, endTime);
|
|
@@ -983,16 +1034,12 @@ export class MidyGM1 {
|
|
|
983
1034
|
}
|
|
984
1035
|
return -1;
|
|
985
1036
|
}
|
|
986
|
-
noteOff(channelNumber, noteNumber, velocity, scheduleTime) {
|
|
987
|
-
scheduleTime ??= this.audioContext.currentTime;
|
|
988
|
-
return this.scheduleNoteOff(channelNumber, noteNumber, velocity, scheduleTime, false);
|
|
989
|
-
}
|
|
990
1037
|
releaseSustainPedal(channelNumber, halfVelocity, scheduleTime) {
|
|
991
1038
|
const velocity = halfVelocity * 2;
|
|
992
1039
|
const channel = this.channels[channelNumber];
|
|
993
1040
|
const promises = [];
|
|
994
1041
|
for (let i = 0; i < channel.sustainNotes.length; i++) {
|
|
995
|
-
const promise = this.
|
|
1042
|
+
const promise = this.noteOff(channelNumber, channel.sustainNotes[i].noteNumber, velocity, scheduleTime);
|
|
996
1043
|
promises.push(promise);
|
|
997
1044
|
}
|
|
998
1045
|
channel.sustainNotes = [];
|
package/esm/midy-GM2.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ export class MidyGM2 {
|
|
|
44
44
|
soundFontTable: never[][];
|
|
45
45
|
voiceCounter: Map<any, any>;
|
|
46
46
|
voiceCache: Map<any, any>;
|
|
47
|
+
realtimeVoiceCache: Map<any, any>;
|
|
47
48
|
isPlaying: boolean;
|
|
48
49
|
isPausing: boolean;
|
|
49
50
|
isPaused: boolean;
|
|
@@ -173,18 +174,17 @@ export class MidyGM2 {
|
|
|
173
174
|
setFilterEnvelope(channel: any, note: any, scheduleTime: any): void;
|
|
174
175
|
startModulation(channel: any, note: any, scheduleTime: any): void;
|
|
175
176
|
startVibrato(channel: any, note: any, scheduleTime: any): void;
|
|
176
|
-
getAudioBuffer(channel: any, noteNumber: any, velocity: any, voiceParams: any): Promise<any>;
|
|
177
|
-
|
|
177
|
+
getAudioBuffer(channel: any, noteNumber: any, velocity: any, voiceParams: any, realtime: any): Promise<any>;
|
|
178
|
+
setNoteAudioNode(channel: any, note: any, realtime: any): Promise<any>;
|
|
178
179
|
handleExclusiveClass(note: any, channelNumber: any, startTime: any): void;
|
|
179
180
|
handleDrumExclusiveClass(note: any, channelNumber: any, startTime: any): void;
|
|
180
|
-
|
|
181
|
-
noteOn(channelNumber: any, noteNumber: any, velocity: any,
|
|
181
|
+
setNoteRouting(channelNumber: any, note: any, startTime: any): void;
|
|
182
|
+
noteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
182
183
|
disconnectNote(note: any): void;
|
|
183
184
|
releaseNote(channel: any, note: any, endTime: any): Promise<any>;
|
|
184
|
-
|
|
185
|
+
noteOff(channelNumber: any, noteNumber: any, velocity: any, endTime: any, force: any): void;
|
|
185
186
|
setNoteIndex(channel: any, index: any): void;
|
|
186
187
|
findNoteOffIndex(channel: any, noteNumber: any): any;
|
|
187
|
-
noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): void;
|
|
188
188
|
releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
|
|
189
189
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
|
|
190
190
|
createMessageHandlers(): any[];
|
|
@@ -312,27 +312,4 @@ export class MidyGM2 {
|
|
|
312
312
|
handleSysEx(data: any, scheduleTime: any): void;
|
|
313
313
|
scheduleTask(callback: any, scheduleTime: any): Promise<any>;
|
|
314
314
|
}
|
|
315
|
-
declare class Note {
|
|
316
|
-
constructor(noteNumber: any, velocity: any, startTime: any, voice: any, voiceParams: any);
|
|
317
|
-
index: number;
|
|
318
|
-
ending: boolean;
|
|
319
|
-
bufferSource: any;
|
|
320
|
-
filterNode: any;
|
|
321
|
-
filterDepth: any;
|
|
322
|
-
volumeEnvelopeNode: any;
|
|
323
|
-
volumeDepth: any;
|
|
324
|
-
modulationLFO: any;
|
|
325
|
-
modulationDepth: any;
|
|
326
|
-
vibratoLFO: any;
|
|
327
|
-
vibratoDepth: any;
|
|
328
|
-
reverbSend: any;
|
|
329
|
-
chorusSend: any;
|
|
330
|
-
portamentoNoteNumber: number;
|
|
331
|
-
noteNumber: any;
|
|
332
|
-
velocity: any;
|
|
333
|
-
startTime: any;
|
|
334
|
-
voice: any;
|
|
335
|
-
voiceParams: any;
|
|
336
|
-
}
|
|
337
|
-
export {};
|
|
338
315
|
//# sourceMappingURL=midy-GM2.d.ts.map
|
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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"}
|