@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/script/midy-GM1.js
CHANGED
|
@@ -4,7 +4,19 @@ exports.MidyGM1 = void 0;
|
|
|
4
4
|
const midi_file_1 = require("midi-file");
|
|
5
5
|
const soundfont_parser_1 = require("@marmooo/soundfont-parser");
|
|
6
6
|
class Note {
|
|
7
|
-
constructor(noteNumber, velocity, startTime
|
|
7
|
+
constructor(noteNumber, velocity, startTime) {
|
|
8
|
+
Object.defineProperty(this, "voice", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: void 0
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(this, "voiceParams", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: void 0
|
|
19
|
+
});
|
|
8
20
|
Object.defineProperty(this, "index", {
|
|
9
21
|
enumerable: true,
|
|
10
22
|
configurable: true,
|
|
@@ -17,6 +29,12 @@ class Note {
|
|
|
17
29
|
writable: true,
|
|
18
30
|
value: false
|
|
19
31
|
});
|
|
32
|
+
Object.defineProperty(this, "pending", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: true
|
|
37
|
+
});
|
|
20
38
|
Object.defineProperty(this, "bufferSource", {
|
|
21
39
|
enumerable: true,
|
|
22
40
|
configurable: true,
|
|
@@ -62,8 +80,6 @@ class Note {
|
|
|
62
80
|
this.noteNumber = noteNumber;
|
|
63
81
|
this.velocity = velocity;
|
|
64
82
|
this.startTime = startTime;
|
|
65
|
-
this.voice = voice;
|
|
66
|
-
this.voiceParams = voiceParams;
|
|
67
83
|
}
|
|
68
84
|
}
|
|
69
85
|
// normalized to 0-1 for use with the SF2 modulator model
|
|
@@ -217,6 +233,12 @@ class MidyGM1 {
|
|
|
217
233
|
writable: true,
|
|
218
234
|
value: new Map()
|
|
219
235
|
});
|
|
236
|
+
Object.defineProperty(this, "realtimeVoiceCache", {
|
|
237
|
+
enumerable: true,
|
|
238
|
+
configurable: true,
|
|
239
|
+
writable: true,
|
|
240
|
+
value: new Map()
|
|
241
|
+
});
|
|
220
242
|
Object.defineProperty(this, "isPlaying", {
|
|
221
243
|
enumerable: true,
|
|
222
244
|
configurable: true,
|
|
@@ -447,10 +469,10 @@ class MidyGM1 {
|
|
|
447
469
|
const startTime = event.startTime + schedulingOffset;
|
|
448
470
|
switch (event.type) {
|
|
449
471
|
case "noteOn":
|
|
450
|
-
await this.
|
|
472
|
+
await this.noteOn(event.channel, event.noteNumber, event.velocity, startTime);
|
|
451
473
|
break;
|
|
452
474
|
case "noteOff": {
|
|
453
|
-
const notePromise = this.
|
|
475
|
+
const notePromise = this.noteOff(event.channel, event.noteNumber, event.velocity, startTime, false);
|
|
454
476
|
if (notePromise)
|
|
455
477
|
this.notePromises.push(notePromise);
|
|
456
478
|
break;
|
|
@@ -483,6 +505,7 @@ class MidyGM1 {
|
|
|
483
505
|
this.exclusiveClassNotes.fill(undefined);
|
|
484
506
|
this.drumExclusiveClassNotes.fill(undefined);
|
|
485
507
|
this.voiceCache.clear();
|
|
508
|
+
this.realtimeVoiceCache.clear();
|
|
486
509
|
for (let i = 0; i < this.channels.length; i++) {
|
|
487
510
|
this.channels[i].scheduledNotes = [];
|
|
488
511
|
this.resetChannelStates(i);
|
|
@@ -520,7 +543,6 @@ class MidyGM1 {
|
|
|
520
543
|
this.notePromises = [];
|
|
521
544
|
while (queueIndex < this.timeline.length) {
|
|
522
545
|
const now = this.audioContext.currentTime;
|
|
523
|
-
queueIndex = await this.scheduleTimelineEvents(now, queueIndex);
|
|
524
546
|
if (this.isPausing) {
|
|
525
547
|
await this.stopNotes(0, true, now);
|
|
526
548
|
await this.audioContext.suspend();
|
|
@@ -542,6 +564,7 @@ class MidyGM1 {
|
|
|
542
564
|
this.isSeeking = false;
|
|
543
565
|
continue;
|
|
544
566
|
}
|
|
567
|
+
queueIndex = await this.scheduleTimelineEvents(now, queueIndex);
|
|
545
568
|
const waitTime = now + this.noteCheckInterval;
|
|
546
569
|
await this.scheduleTask(() => { }, waitTime);
|
|
547
570
|
}
|
|
@@ -619,7 +642,7 @@ class MidyGM1 {
|
|
|
619
642
|
const channel = this.channels[channelNumber];
|
|
620
643
|
const promises = [];
|
|
621
644
|
this.processActiveNotes(channel, scheduleTime, (note) => {
|
|
622
|
-
const promise = this.
|
|
645
|
+
const promise = this.noteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force);
|
|
623
646
|
this.notePromises.push(promise);
|
|
624
647
|
promises.push(promise);
|
|
625
648
|
});
|
|
@@ -629,7 +652,7 @@ class MidyGM1 {
|
|
|
629
652
|
const channel = this.channels[channelNumber];
|
|
630
653
|
const promises = [];
|
|
631
654
|
this.processScheduledNotes(channel, (note) => {
|
|
632
|
-
const promise = this.
|
|
655
|
+
const promise = this.noteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force);
|
|
633
656
|
this.notePromises.push(promise);
|
|
634
657
|
promises.push(promise);
|
|
635
658
|
});
|
|
@@ -662,7 +685,7 @@ class MidyGM1 {
|
|
|
662
685
|
if (!this.isPlaying || this.isPaused)
|
|
663
686
|
return;
|
|
664
687
|
const now = this.audioContext.currentTime;
|
|
665
|
-
this.resumeTime
|
|
688
|
+
this.resumeTime = now - this.startTime - this.startDelay;
|
|
666
689
|
this.isPausing = true;
|
|
667
690
|
await this.playPromise;
|
|
668
691
|
this.isPausing = false;
|
|
@@ -688,11 +711,13 @@ class MidyGM1 {
|
|
|
688
711
|
if (totalTime < event.startTime)
|
|
689
712
|
totalTime = event.startTime;
|
|
690
713
|
}
|
|
691
|
-
return totalTime;
|
|
714
|
+
return totalTime + this.startDelay;
|
|
692
715
|
}
|
|
693
716
|
currentTime() {
|
|
717
|
+
if (!this.isPlaying)
|
|
718
|
+
return this.resumeTime;
|
|
694
719
|
const now = this.audioContext.currentTime;
|
|
695
|
-
return
|
|
720
|
+
return now + this.resumeTime - this.startTime;
|
|
696
721
|
}
|
|
697
722
|
processScheduledNotes(channel, callback) {
|
|
698
723
|
const scheduledNotes = channel.scheduledNotes;
|
|
@@ -831,31 +856,42 @@ class MidyGM1 {
|
|
|
831
856
|
note.modulationLFO.connect(note.volumeDepth);
|
|
832
857
|
note.volumeDepth.connect(note.volumeEnvelopeNode.gain);
|
|
833
858
|
}
|
|
834
|
-
async getAudioBuffer(channel, noteNumber, velocity, voiceParams) {
|
|
859
|
+
async getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime) {
|
|
835
860
|
const audioBufferId = this.getVoiceId(channel, noteNumber, velocity);
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
this.voiceCache.delete(audioBufferId);
|
|
841
|
-
}
|
|
842
|
-
return cache.audioBuffer;
|
|
843
|
-
}
|
|
844
|
-
else {
|
|
845
|
-
const maxCount = this.voiceCounter.get(audioBufferId) ?? 0;
|
|
861
|
+
if (realtime) {
|
|
862
|
+
const cachedAudioBuffer = this.realtimeVoiceCache.get(audioBufferId);
|
|
863
|
+
if (cachedAudioBuffer)
|
|
864
|
+
return cachedAudioBuffer;
|
|
846
865
|
const audioBuffer = await this.createAudioBuffer(voiceParams);
|
|
847
|
-
|
|
848
|
-
this.voiceCache.set(audioBufferId, cache);
|
|
866
|
+
this.realtimeVoiceCache.set(audioBufferId, audioBuffer);
|
|
849
867
|
return audioBuffer;
|
|
850
868
|
}
|
|
869
|
+
else {
|
|
870
|
+
const cache = this.voiceCache.get(audioBufferId);
|
|
871
|
+
if (cache) {
|
|
872
|
+
cache.counter += 1;
|
|
873
|
+
if (cache.maxCount <= cache.counter) {
|
|
874
|
+
this.voiceCache.delete(audioBufferId);
|
|
875
|
+
}
|
|
876
|
+
return cache.audioBuffer;
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
const maxCount = this.voiceCounter.get(audioBufferId) ?? 0;
|
|
880
|
+
const audioBuffer = await this.createAudioBuffer(voiceParams);
|
|
881
|
+
const cache = { audioBuffer, maxCount, counter: 1 };
|
|
882
|
+
this.voiceCache.set(audioBufferId, cache);
|
|
883
|
+
return audioBuffer;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
851
886
|
}
|
|
852
|
-
async
|
|
887
|
+
async setNoteAudioNode(channel, note, realtime) {
|
|
853
888
|
const now = this.audioContext.currentTime;
|
|
889
|
+
const { noteNumber, velocity, startTime } = note;
|
|
854
890
|
const state = channel.state;
|
|
855
891
|
const controllerState = this.getControllerState(channel, noteNumber, velocity);
|
|
856
|
-
const voiceParams = voice.getAllParams(controllerState);
|
|
857
|
-
|
|
858
|
-
const audioBuffer = await this.getAudioBuffer(channel, noteNumber, velocity, voiceParams);
|
|
892
|
+
const voiceParams = note.voice.getAllParams(controllerState);
|
|
893
|
+
note.voiceParams = voiceParams;
|
|
894
|
+
const audioBuffer = await this.getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime);
|
|
859
895
|
note.bufferSource = this.createBufferSource(voiceParams, audioBuffer);
|
|
860
896
|
note.volumeEnvelopeNode = new GainNode(this.audioContext);
|
|
861
897
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
@@ -882,14 +918,31 @@ class MidyGM1 {
|
|
|
882
918
|
if (prev) {
|
|
883
919
|
const [prevNote, prevChannelNumber] = prev;
|
|
884
920
|
if (prevNote && !prevNote.ending) {
|
|
885
|
-
this.
|
|
921
|
+
this.noteOff(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
|
|
886
922
|
startTime, true);
|
|
887
923
|
}
|
|
888
924
|
}
|
|
889
925
|
this.exclusiveClassNotes[exclusiveClass] = [note, channelNumber];
|
|
890
926
|
}
|
|
891
|
-
|
|
927
|
+
setNoteRouting(channelNumber, note, startTime) {
|
|
892
928
|
const channel = this.channels[channelNumber];
|
|
929
|
+
const volumeEnvelopeNode = note.volumeEnvelopeNode;
|
|
930
|
+
volumeEnvelopeNode.connect(channel.gainL);
|
|
931
|
+
volumeEnvelopeNode.connect(channel.gainR);
|
|
932
|
+
if (0.5 <= channel.state.sustainPedal) {
|
|
933
|
+
channel.sustainNotes.push(note);
|
|
934
|
+
}
|
|
935
|
+
this.handleExclusiveClass(note, channelNumber, startTime);
|
|
936
|
+
}
|
|
937
|
+
async noteOn(channelNumber, noteNumber, velocity, startTime) {
|
|
938
|
+
const channel = this.channels[channelNumber];
|
|
939
|
+
const realtime = startTime === undefined;
|
|
940
|
+
if (realtime)
|
|
941
|
+
startTime = this.audioContext.currentTime;
|
|
942
|
+
const note = new Note(noteNumber, velocity, startTime);
|
|
943
|
+
const scheduledNotes = channel.scheduledNotes;
|
|
944
|
+
note.index = scheduledNotes.length;
|
|
945
|
+
scheduledNotes.push(note);
|
|
893
946
|
const programNumber = channel.programNumber;
|
|
894
947
|
const bankTable = this.soundFontTable[programNumber];
|
|
895
948
|
if (!bankTable)
|
|
@@ -899,23 +952,16 @@ class MidyGM1 {
|
|
|
899
952
|
if (soundFontIndex === undefined)
|
|
900
953
|
return;
|
|
901
954
|
const soundFont = this.soundFonts[soundFontIndex];
|
|
902
|
-
|
|
903
|
-
if (!voice)
|
|
955
|
+
note.voice = soundFont.getVoice(bank, programNumber, noteNumber, velocity);
|
|
956
|
+
if (!note.voice)
|
|
904
957
|
return;
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
note.
|
|
908
|
-
|
|
909
|
-
|
|
958
|
+
await this.setNoteAudioNode(channel, note, realtime);
|
|
959
|
+
this.setNoteRouting(channelNumber, note, startTime);
|
|
960
|
+
note.pending = false;
|
|
961
|
+
const off = note.offEvent;
|
|
962
|
+
if (off) {
|
|
963
|
+
this.noteOff(channelNumber, noteNumber, off.velocity, off.startTime);
|
|
910
964
|
}
|
|
911
|
-
this.handleExclusiveClass(note, channelNumber, startTime);
|
|
912
|
-
const scheduledNotes = channel.scheduledNotes;
|
|
913
|
-
note.index = scheduledNotes.length;
|
|
914
|
-
scheduledNotes.push(note);
|
|
915
|
-
}
|
|
916
|
-
noteOn(channelNumber, noteNumber, velocity, scheduleTime) {
|
|
917
|
-
scheduleTime ??= this.audioContext.currentTime;
|
|
918
|
-
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, scheduleTime, undefined);
|
|
919
965
|
}
|
|
920
966
|
disconnectNote(note) {
|
|
921
967
|
note.bufferSource.disconnect();
|
|
@@ -928,6 +974,7 @@ class MidyGM1 {
|
|
|
928
974
|
}
|
|
929
975
|
}
|
|
930
976
|
releaseNote(channel, note, endTime) {
|
|
977
|
+
endTime ??= this.audioContext.currentTime;
|
|
931
978
|
const volRelease = endTime + note.voiceParams.volRelease;
|
|
932
979
|
const modRelease = endTime + note.voiceParams.modRelease;
|
|
933
980
|
const stopTime = Math.min(volRelease, modRelease);
|
|
@@ -948,7 +995,7 @@ class MidyGM1 {
|
|
|
948
995
|
}, stopTime);
|
|
949
996
|
});
|
|
950
997
|
}
|
|
951
|
-
|
|
998
|
+
noteOff(channelNumber, noteNumber, velocity, endTime, force) {
|
|
952
999
|
const channel = this.channels[channelNumber];
|
|
953
1000
|
if (!force && 0.5 <= channel.state.sustainPedal)
|
|
954
1001
|
return;
|
|
@@ -956,6 +1003,10 @@ class MidyGM1 {
|
|
|
956
1003
|
if (index < 0)
|
|
957
1004
|
return;
|
|
958
1005
|
const note = channel.scheduledNotes[index];
|
|
1006
|
+
if (note.pending) {
|
|
1007
|
+
note.offEvent = { velocity, startTime: endTime };
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
959
1010
|
note.ending = true;
|
|
960
1011
|
this.setNoteIndex(channel, index);
|
|
961
1012
|
this.releaseNote(channel, note, endTime);
|
|
@@ -986,16 +1037,12 @@ class MidyGM1 {
|
|
|
986
1037
|
}
|
|
987
1038
|
return -1;
|
|
988
1039
|
}
|
|
989
|
-
noteOff(channelNumber, noteNumber, velocity, scheduleTime) {
|
|
990
|
-
scheduleTime ??= this.audioContext.currentTime;
|
|
991
|
-
return this.scheduleNoteOff(channelNumber, noteNumber, velocity, scheduleTime, false);
|
|
992
|
-
}
|
|
993
1040
|
releaseSustainPedal(channelNumber, halfVelocity, scheduleTime) {
|
|
994
1041
|
const velocity = halfVelocity * 2;
|
|
995
1042
|
const channel = this.channels[channelNumber];
|
|
996
1043
|
const promises = [];
|
|
997
1044
|
for (let i = 0; i < channel.sustainNotes.length; i++) {
|
|
998
|
-
const promise = this.
|
|
1045
|
+
const promise = this.noteOff(channelNumber, channel.sustainNotes[i].noteNumber, velocity, scheduleTime);
|
|
999
1046
|
promises.push(promise);
|
|
1000
1047
|
}
|
|
1001
1048
|
channel.sustainNotes = [];
|
package/script/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/script/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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"}
|