@marmooo/midy 0.1.1 → 0.1.3
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/+esm.d.ts +153 -0
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +1 -0
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.2 → soundfont-parser@0.0.4}/+esm.js +73 -66
- package/esm/midy-GM1.d.ts +18 -14
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +133 -110
- package/esm/midy-GM2.d.ts +36 -30
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +190 -158
- package/esm/midy-GMLite.d.ts +16 -14
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +123 -112
- package/esm/midy.d.ts +33 -31
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +191 -185
- package/package.json +1 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts +153 -0
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +1 -0
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.2 → soundfont-parser@0.0.4}/+esm.js +75 -68
- package/script/midy-GM1.d.ts +18 -14
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +133 -110
- package/script/midy-GM2.d.ts +36 -30
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +190 -158
- package/script/midy-GMLite.d.ts +16 -14
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +123 -112
- package/script/midy.d.ts +33 -31
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +191 -185
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts +0 -135
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts.map +0 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts +0 -135
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts.map +0 -1
package/script/midy-GM1.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MidyGM1 = 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.4/+esm.js");
|
|
6
6
|
class Note {
|
|
7
7
|
constructor(noteNumber, velocity, startTime, instrumentKey) {
|
|
8
8
|
Object.defineProperty(this, "bufferSource", {
|
|
@@ -11,25 +11,43 @@ class Note {
|
|
|
11
11
|
writable: true,
|
|
12
12
|
value: void 0
|
|
13
13
|
});
|
|
14
|
-
Object.defineProperty(this, "
|
|
14
|
+
Object.defineProperty(this, "filterNode", {
|
|
15
15
|
enumerable: true,
|
|
16
16
|
configurable: true,
|
|
17
17
|
writable: true,
|
|
18
18
|
value: void 0
|
|
19
19
|
});
|
|
20
|
-
Object.defineProperty(this, "
|
|
20
|
+
Object.defineProperty(this, "volumeNode", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: void 0
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "volumeDepth", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: void 0
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "modulationLFO", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: void 0
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(this, "modulationDepth", {
|
|
21
39
|
enumerable: true,
|
|
22
40
|
configurable: true,
|
|
23
41
|
writable: true,
|
|
24
42
|
value: void 0
|
|
25
43
|
});
|
|
26
|
-
Object.defineProperty(this, "
|
|
44
|
+
Object.defineProperty(this, "vibratoLFO", {
|
|
27
45
|
enumerable: true,
|
|
28
46
|
configurable: true,
|
|
29
47
|
writable: true,
|
|
30
48
|
value: void 0
|
|
31
49
|
});
|
|
32
|
-
Object.defineProperty(this, "
|
|
50
|
+
Object.defineProperty(this, "vibratoDepth", {
|
|
33
51
|
enumerable: true,
|
|
34
52
|
configurable: true,
|
|
35
53
|
writable: true,
|
|
@@ -147,8 +165,8 @@ class MidyGM1 {
|
|
|
147
165
|
});
|
|
148
166
|
this.audioContext = audioContext;
|
|
149
167
|
this.masterGain = new GainNode(audioContext);
|
|
150
|
-
this.masterGain.connect(audioContext.destination);
|
|
151
168
|
this.channels = this.createChannels(audioContext);
|
|
169
|
+
this.masterGain.connect(audioContext.destination);
|
|
152
170
|
this.GM1SystemOn();
|
|
153
171
|
}
|
|
154
172
|
initSoundFontTable() {
|
|
@@ -192,6 +210,7 @@ class MidyGM1 {
|
|
|
192
210
|
const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
|
|
193
211
|
gainL.connect(merger, 0, 0);
|
|
194
212
|
gainR.connect(merger, 0, 1);
|
|
213
|
+
merger.connect(this.masterGain);
|
|
195
214
|
return {
|
|
196
215
|
gainL,
|
|
197
216
|
gainR,
|
|
@@ -315,7 +334,7 @@ class MidyGM1 {
|
|
|
315
334
|
const t = this.audioContext.currentTime + offset;
|
|
316
335
|
queueIndex = await this.scheduleTimelineEvents(t, offset, queueIndex);
|
|
317
336
|
if (this.isPausing) {
|
|
318
|
-
await this.stopNotes();
|
|
337
|
+
await this.stopNotes(0, true);
|
|
319
338
|
this.notePromises = [];
|
|
320
339
|
resolve();
|
|
321
340
|
this.isPausing = false;
|
|
@@ -323,7 +342,7 @@ class MidyGM1 {
|
|
|
323
342
|
return;
|
|
324
343
|
}
|
|
325
344
|
else if (this.isStopping) {
|
|
326
|
-
await this.stopNotes();
|
|
345
|
+
await this.stopNotes(0, true);
|
|
327
346
|
this.notePromises = [];
|
|
328
347
|
resolve();
|
|
329
348
|
this.isStopping = false;
|
|
@@ -331,7 +350,7 @@ class MidyGM1 {
|
|
|
331
350
|
return;
|
|
332
351
|
}
|
|
333
352
|
else if (this.isSeeking) {
|
|
334
|
-
this.stopNotes();
|
|
353
|
+
this.stopNotes(0, true);
|
|
335
354
|
this.startTime = this.audioContext.currentTime;
|
|
336
355
|
queueIndex = this.getQueueIndex(this.resumeTime);
|
|
337
356
|
offset = this.resumeTime - this.startTime;
|
|
@@ -412,21 +431,24 @@ class MidyGM1 {
|
|
|
412
431
|
}
|
|
413
432
|
return { instruments, timeline };
|
|
414
433
|
}
|
|
415
|
-
|
|
434
|
+
async stopChannelNotes(channelNumber, velocity, stopPedal) {
|
|
416
435
|
const now = this.audioContext.currentTime;
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
this.notePromises.push(promise);
|
|
425
|
-
}
|
|
426
|
-
});
|
|
436
|
+
const channel = this.channels[channelNumber];
|
|
437
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
438
|
+
noteList.forEach((note) => {
|
|
439
|
+
if (note) {
|
|
440
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
|
|
441
|
+
this.notePromises.push(promise);
|
|
442
|
+
}
|
|
427
443
|
});
|
|
428
|
-
channel.scheduledNotes.clear();
|
|
429
444
|
});
|
|
445
|
+
channel.scheduledNotes.clear();
|
|
446
|
+
await Promise.all(this.notePromises);
|
|
447
|
+
}
|
|
448
|
+
stopNotes(velocity, stopPedal) {
|
|
449
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
450
|
+
this.stopChannelNotes(i, velocity, stopPedal);
|
|
451
|
+
}
|
|
430
452
|
return Promise.all(this.notePromises);
|
|
431
453
|
}
|
|
432
454
|
async start() {
|
|
@@ -494,10 +516,6 @@ class MidyGM1 {
|
|
|
494
516
|
}
|
|
495
517
|
return noteList[0];
|
|
496
518
|
}
|
|
497
|
-
connectEffects(channel, gainNode) {
|
|
498
|
-
gainNode.connect(channel.merger);
|
|
499
|
-
merger.connect(this.masterGain);
|
|
500
|
-
}
|
|
501
519
|
cbToRatio(cb) {
|
|
502
520
|
return Math.pow(10, cb / 200);
|
|
503
521
|
}
|
|
@@ -512,27 +530,41 @@ class MidyGM1 {
|
|
|
512
530
|
return instrumentKey.playbackRate(noteNumber) *
|
|
513
531
|
Math.pow(2, semitoneOffset / 12);
|
|
514
532
|
}
|
|
515
|
-
setVolumeEnvelope(
|
|
516
|
-
const { instrumentKey, startTime
|
|
517
|
-
note.
|
|
518
|
-
|
|
519
|
-
if (volume === 0)
|
|
520
|
-
volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
|
|
521
|
-
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation) *
|
|
522
|
-
volume;
|
|
533
|
+
setVolumeEnvelope(note) {
|
|
534
|
+
const { instrumentKey, startTime } = note;
|
|
535
|
+
note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
|
|
536
|
+
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
|
|
523
537
|
const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
|
|
524
538
|
const volDelay = startTime + instrumentKey.volDelay;
|
|
525
539
|
const volAttack = volDelay + instrumentKey.volAttack;
|
|
526
540
|
const volHold = volAttack + instrumentKey.volHold;
|
|
527
541
|
const volDecay = volHold + instrumentKey.volDecay;
|
|
528
|
-
note.
|
|
542
|
+
note.volumeNode.gain
|
|
529
543
|
.setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
|
|
530
544
|
.exponentialRampToValueAtTime(attackVolume, volAttack)
|
|
531
545
|
.setValueAtTime(attackVolume, volHold)
|
|
532
546
|
.linearRampToValueAtTime(sustainVolume, volDecay);
|
|
533
547
|
}
|
|
534
|
-
|
|
535
|
-
const { instrumentKey,
|
|
548
|
+
setPitch(note, semitoneOffset) {
|
|
549
|
+
const { instrumentKey, noteNumber, startTime } = note;
|
|
550
|
+
const modEnvToPitch = instrumentKey.modEnvToPitch / 100;
|
|
551
|
+
note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
|
|
552
|
+
if (modEnvToPitch === 0)
|
|
553
|
+
return;
|
|
554
|
+
const basePitch = note.bufferSource.playbackRate.value;
|
|
555
|
+
const peekPitch = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset + modEnvToPitch);
|
|
556
|
+
const modDelay = startTime + instrumentKey.modDelay;
|
|
557
|
+
const modAttack = modDelay + instrumentKey.modAttack;
|
|
558
|
+
const modHold = modAttack + instrumentKey.modHold;
|
|
559
|
+
const modDecay = modHold + instrumentKey.modDecay;
|
|
560
|
+
note.bufferSource.playbackRate.value
|
|
561
|
+
.setValueAtTime(basePitch, modDelay)
|
|
562
|
+
.exponentialRampToValueAtTime(peekPitch, modAttack)
|
|
563
|
+
.setValueAtTime(peekPitch, modHold)
|
|
564
|
+
.linearRampToValueAtTime(basePitch, modDecay);
|
|
565
|
+
}
|
|
566
|
+
setFilterNode(channel, note) {
|
|
567
|
+
const { instrumentKey, noteNumber, startTime } = note;
|
|
536
568
|
const softPedalFactor = 1 -
|
|
537
569
|
(0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
|
|
538
570
|
const maxFreq = this.audioContext.sampleRate / 2;
|
|
@@ -541,13 +573,13 @@ class MidyGM1 {
|
|
|
541
573
|
const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
|
|
542
574
|
const sustainFreq = (baseFreq +
|
|
543
575
|
(peekFreq - baseFreq) * (1 - instrumentKey.modSustain)) * softPedalFactor;
|
|
576
|
+
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
577
|
+
const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
|
|
578
|
+
const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
|
|
544
579
|
const modDelay = startTime + instrumentKey.modDelay;
|
|
545
580
|
const modAttack = modDelay + instrumentKey.modAttack;
|
|
546
581
|
const modHold = modAttack + instrumentKey.modHold;
|
|
547
582
|
const modDecay = modHold + instrumentKey.modDecay;
|
|
548
|
-
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
549
|
-
const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
|
|
550
|
-
const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
|
|
551
583
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
552
584
|
type: "lowpass",
|
|
553
585
|
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
@@ -558,35 +590,49 @@ class MidyGM1 {
|
|
|
558
590
|
.exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
|
|
559
591
|
.setValueAtTime(adjustedPeekFreq, modHold)
|
|
560
592
|
.linearRampToValueAtTime(adjustedSustainFreq, modDecay);
|
|
561
|
-
note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modEnvToPitch, modDelay);
|
|
562
593
|
}
|
|
563
|
-
startModulation(channel, note,
|
|
594
|
+
startModulation(channel, note, startTime) {
|
|
564
595
|
const { instrumentKey } = note;
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
});
|
|
568
|
-
note.modLFO = new OscillatorNode(this.audioContext, {
|
|
596
|
+
const { modLfoToPitch, modLfoToVolume } = instrumentKey;
|
|
597
|
+
note.modulationLFO = new OscillatorNode(this.audioContext, {
|
|
569
598
|
frequency: this.centToHz(instrumentKey.freqModLFO),
|
|
570
599
|
});
|
|
571
|
-
note.
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
600
|
+
note.filterDepth = new GainNode(this.audioContext, {
|
|
601
|
+
gain: instrumentKey.modLfoToFilterFc,
|
|
602
|
+
});
|
|
603
|
+
const modulationDepth = Math.abs(modLfoToPitch) + channel.modulationDepth;
|
|
604
|
+
const modulationDepthSign = (0 < modLfoToPitch) ? 1 : -1;
|
|
605
|
+
note.modulationDepth = new GainNode(this.audioContext, {
|
|
606
|
+
gain: modulationDepth * modulationDepthSign,
|
|
607
|
+
});
|
|
608
|
+
const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
|
|
609
|
+
const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
|
|
610
|
+
note.volumeDepth = new GainNode(this.audioContext, {
|
|
611
|
+
gain: volumeDepth * volumeDepthSign,
|
|
612
|
+
});
|
|
613
|
+
note.modulationLFO.start(startTime + instrumentKey.delayModLFO);
|
|
614
|
+
note.modulationLFO.connect(note.filterDepth);
|
|
615
|
+
note.filterDepth.connect(note.filterNode.frequency);
|
|
616
|
+
note.modulationLFO.connect(note.modulationDepth);
|
|
617
|
+
note.modulationDepth.connect(note.bufferSource.detune);
|
|
618
|
+
note.modulationLFO.connect(note.volumeDepth);
|
|
619
|
+
note.volumeDepth.connect(note.volumeNode.gain);
|
|
576
620
|
}
|
|
577
621
|
async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
|
|
578
622
|
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
579
623
|
const note = new Note(noteNumber, velocity, startTime, instrumentKey);
|
|
580
624
|
note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
|
|
581
|
-
|
|
582
|
-
this.setVolumeEnvelope(
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
625
|
+
this.setFilterNode(channel, note);
|
|
626
|
+
this.setVolumeEnvelope(note);
|
|
627
|
+
if (0 < channel.modulationDepth) {
|
|
628
|
+
this.setPitch(note, semitoneOffset);
|
|
629
|
+
this.startModulation(channel, note, startTime);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
|
|
587
633
|
}
|
|
588
634
|
note.bufferSource.connect(note.filterNode);
|
|
589
|
-
note.filterNode.connect(note.
|
|
635
|
+
note.filterNode.connect(note.volumeNode);
|
|
590
636
|
note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
|
|
591
637
|
return note;
|
|
592
638
|
}
|
|
@@ -602,7 +648,8 @@ class MidyGM1 {
|
|
|
602
648
|
if (!instrumentKey)
|
|
603
649
|
return;
|
|
604
650
|
const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
|
|
605
|
-
|
|
651
|
+
note.volumeNode.connect(channel.gainL);
|
|
652
|
+
note.volumeNode.connect(channel.gainR);
|
|
606
653
|
const scheduledNotes = channel.scheduledNotes;
|
|
607
654
|
if (scheduledNotes.has(noteNumber)) {
|
|
608
655
|
scheduledNotes.get(noteNumber).push(note);
|
|
@@ -631,17 +678,14 @@ class MidyGM1 {
|
|
|
631
678
|
const velocityRate = (velocity + 127) / 127;
|
|
632
679
|
const volEndTime = stopTime +
|
|
633
680
|
note.instrumentKey.volRelease * velocityRate;
|
|
634
|
-
note.
|
|
681
|
+
note.volumeNode.gain
|
|
635
682
|
.cancelScheduledValues(stopTime)
|
|
636
683
|
.linearRampToValueAtTime(0, volEndTime);
|
|
637
|
-
const
|
|
638
|
-
const baseFreq = this.centToHz(note.instrumentKey.initialFilterFc);
|
|
639
|
-
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
640
|
-
const modEndTime = stopTime +
|
|
684
|
+
const modRelease = stopTime +
|
|
641
685
|
note.instrumentKey.modRelease * velocityRate;
|
|
642
686
|
note.filterNode.frequency
|
|
643
687
|
.cancelScheduledValues(stopTime)
|
|
644
|
-
.linearRampToValueAtTime(
|
|
688
|
+
.linearRampToValueAtTime(0, modRelease);
|
|
645
689
|
note.ending = true;
|
|
646
690
|
this.scheduleTask(() => {
|
|
647
691
|
note.bufferSource.loop = false;
|
|
@@ -650,15 +694,17 @@ class MidyGM1 {
|
|
|
650
694
|
note.bufferSource.onended = () => {
|
|
651
695
|
scheduledNotes[i] = null;
|
|
652
696
|
note.bufferSource.disconnect();
|
|
697
|
+
note.volumeNode.disconnect();
|
|
653
698
|
note.filterNode.disconnect();
|
|
654
|
-
note.
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
699
|
+
if (note.volumeDepth)
|
|
700
|
+
note.volumeDepth.disconnect();
|
|
701
|
+
if (note.modulationDepth)
|
|
702
|
+
note.modulationDepth.disconnect();
|
|
703
|
+
if (note.modulationLFO)
|
|
704
|
+
note.modulationLFO.stop();
|
|
659
705
|
resolve();
|
|
660
706
|
};
|
|
661
|
-
bufferSource.stop(volEndTime);
|
|
707
|
+
note.bufferSource.stop(volEndTime);
|
|
662
708
|
});
|
|
663
709
|
}
|
|
664
710
|
}
|
|
@@ -671,10 +717,10 @@ class MidyGM1 {
|
|
|
671
717
|
const channel = this.channels[channelNumber];
|
|
672
718
|
const promises = [];
|
|
673
719
|
channel.sustainPedal = false;
|
|
674
|
-
channel.scheduledNotes.forEach((
|
|
675
|
-
|
|
676
|
-
if (
|
|
677
|
-
const { noteNumber } =
|
|
720
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
721
|
+
noteList.forEach((note) => {
|
|
722
|
+
if (note) {
|
|
723
|
+
const { noteNumber } = note;
|
|
678
724
|
const promise = this.releaseNote(channelNumber, noteNumber, velocity);
|
|
679
725
|
promises.push(promise);
|
|
680
726
|
}
|
|
@@ -705,13 +751,13 @@ class MidyGM1 {
|
|
|
705
751
|
channel.program = program;
|
|
706
752
|
}
|
|
707
753
|
handlePitchBendMessage(channelNumber, lsb, msb) {
|
|
708
|
-
const pitchBend = msb * 128 + lsb;
|
|
754
|
+
const pitchBend = msb * 128 + lsb - 8192;
|
|
709
755
|
this.setPitchBend(channelNumber, pitchBend);
|
|
710
756
|
}
|
|
711
757
|
setPitchBend(channelNumber, pitchBend) {
|
|
712
758
|
const channel = this.channels[channelNumber];
|
|
713
759
|
const prevPitchBend = channel.pitchBend;
|
|
714
|
-
channel.pitchBend =
|
|
760
|
+
channel.pitchBend = pitchBend / 8192;
|
|
715
761
|
const detuneChange = (channel.pitchBend - prevPitchBend) *
|
|
716
762
|
channel.pitchBendRange * 100;
|
|
717
763
|
this.updateDetune(channel, detuneChange);
|
|
@@ -719,7 +765,7 @@ class MidyGM1 {
|
|
|
719
765
|
handleControlChange(channelNumber, controller, value) {
|
|
720
766
|
switch (controller) {
|
|
721
767
|
case 1:
|
|
722
|
-
return this.
|
|
768
|
+
return this.setModulationDepth(channelNumber, value);
|
|
723
769
|
case 6:
|
|
724
770
|
return this.dataEntryMSB(channelNumber, value);
|
|
725
771
|
case 7:
|
|
@@ -750,18 +796,19 @@ class MidyGM1 {
|
|
|
750
796
|
const now = this.audioContext.currentTime;
|
|
751
797
|
const activeNotes = this.getActiveNotes(channel, now);
|
|
752
798
|
activeNotes.forEach((activeNote) => {
|
|
753
|
-
if (activeNote.
|
|
754
|
-
|
|
755
|
-
gainNode.gain.setValueAtTime(this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation), now);
|
|
799
|
+
if (activeNote.modulationDepth) {
|
|
800
|
+
activeNote.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
|
|
756
801
|
}
|
|
757
802
|
else {
|
|
803
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
804
|
+
this.setPitch(activeNote, semitoneOffset);
|
|
758
805
|
this.startModulation(channel, activeNote, now);
|
|
759
806
|
}
|
|
760
807
|
});
|
|
761
808
|
}
|
|
762
|
-
|
|
809
|
+
setModulationDepth(channelNumber, modulation) {
|
|
763
810
|
const channel = this.channels[channelNumber];
|
|
764
|
-
channel.
|
|
811
|
+
channel.modulationDepth = (modulation / 127) * channel.modulationDepthRange;
|
|
765
812
|
this.updateModulation(channel);
|
|
766
813
|
}
|
|
767
814
|
setVolume(channelNumber, volume) {
|
|
@@ -913,37 +960,13 @@ class MidyGM1 {
|
|
|
913
960
|
this.updateDetune(channel, detuneChange);
|
|
914
961
|
}
|
|
915
962
|
allSoundOff(channelNumber) {
|
|
916
|
-
|
|
917
|
-
const channel = this.channels[channelNumber];
|
|
918
|
-
const velocity = 0;
|
|
919
|
-
const stopPedal = true;
|
|
920
|
-
const promises = [];
|
|
921
|
-
channel.scheduledNotes.forEach((noteList) => {
|
|
922
|
-
const activeNote = this.getActiveNote(noteList, now);
|
|
923
|
-
if (activeNote) {
|
|
924
|
-
const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
|
|
925
|
-
promises.push(notePromise);
|
|
926
|
-
}
|
|
927
|
-
});
|
|
928
|
-
return promises;
|
|
963
|
+
return this.stopChannelNotes(channelNumber, 0, true);
|
|
929
964
|
}
|
|
930
965
|
resetAllControllers(channelNumber) {
|
|
931
966
|
Object.assign(this.channels[channelNumber], this.effectSettings);
|
|
932
967
|
}
|
|
933
968
|
allNotesOff(channelNumber) {
|
|
934
|
-
|
|
935
|
-
const channel = this.channels[channelNumber];
|
|
936
|
-
const velocity = 0;
|
|
937
|
-
const stopPedal = false;
|
|
938
|
-
const promises = [];
|
|
939
|
-
channel.scheduledNotes.forEach((noteList) => {
|
|
940
|
-
const activeNote = this.getActiveNote(noteList, now);
|
|
941
|
-
if (activeNote) {
|
|
942
|
-
const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
|
|
943
|
-
promises.push(notePromise);
|
|
944
|
-
}
|
|
945
|
-
});
|
|
946
|
-
return promises;
|
|
969
|
+
return this.stopChannelNotes(channelNumber, 0, false);
|
|
947
970
|
}
|
|
948
971
|
handleUniversalNonRealTimeExclusiveMessage(data) {
|
|
949
972
|
switch (data[2]) {
|
|
@@ -1039,7 +1062,7 @@ Object.defineProperty(MidyGM1, "channelSettings", {
|
|
|
1039
1062
|
pitchBend: 0,
|
|
1040
1063
|
fineTuning: 0, // cb
|
|
1041
1064
|
coarseTuning: 0, // cb
|
|
1042
|
-
modulationDepthRange:
|
|
1065
|
+
modulationDepthRange: 50, // cent
|
|
1043
1066
|
}
|
|
1044
1067
|
});
|
|
1045
1068
|
Object.defineProperty(MidyGM1, "effectSettings", {
|
|
@@ -1048,7 +1071,7 @@ Object.defineProperty(MidyGM1, "effectSettings", {
|
|
|
1048
1071
|
writable: true,
|
|
1049
1072
|
value: {
|
|
1050
1073
|
expression: 1,
|
|
1051
|
-
|
|
1074
|
+
modulationDepth: 0,
|
|
1052
1075
|
sustainPedal: false,
|
|
1053
1076
|
rpnMSB: 127,
|
|
1054
1077
|
rpnLSB: 127,
|
package/script/midy-GM2.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export class MidyGM2 {
|
|
|
6
6
|
portamentoTime: number;
|
|
7
7
|
reverbSendLevel: number;
|
|
8
8
|
chorusSendLevel: number;
|
|
9
|
+
vibratoRate: number;
|
|
10
|
+
vibratoDepth: number;
|
|
11
|
+
vibratoDelay: number;
|
|
9
12
|
bank: number;
|
|
10
13
|
bankMSB: number;
|
|
11
14
|
bankLSB: number;
|
|
@@ -19,7 +22,7 @@ export class MidyGM2 {
|
|
|
19
22
|
};
|
|
20
23
|
static effectSettings: {
|
|
21
24
|
expression: number;
|
|
22
|
-
|
|
25
|
+
modulationDepth: number;
|
|
23
26
|
sustainPedal: boolean;
|
|
24
27
|
portamento: boolean;
|
|
25
28
|
sostenutoPedal: boolean;
|
|
@@ -90,6 +93,19 @@ export class MidyGM2 {
|
|
|
90
93
|
};
|
|
91
94
|
masterGain: any;
|
|
92
95
|
channels: any[];
|
|
96
|
+
reverbEffect: {
|
|
97
|
+
input: any;
|
|
98
|
+
output: any;
|
|
99
|
+
};
|
|
100
|
+
chorusEffect: {
|
|
101
|
+
input: any;
|
|
102
|
+
output: any;
|
|
103
|
+
sendGain: any;
|
|
104
|
+
lfo: any;
|
|
105
|
+
lfoGain: any;
|
|
106
|
+
delayNodes: any[];
|
|
107
|
+
feedbackGains: any[];
|
|
108
|
+
};
|
|
93
109
|
initSoundFontTable(): any[];
|
|
94
110
|
addSoundFont(soundFont: any): void;
|
|
95
111
|
loadSoundFont(soundFontUrl: any): Promise<void>;
|
|
@@ -98,19 +114,6 @@ export class MidyGM2 {
|
|
|
98
114
|
gainL: any;
|
|
99
115
|
gainR: any;
|
|
100
116
|
merger: any;
|
|
101
|
-
reverbEffect: {
|
|
102
|
-
input: any;
|
|
103
|
-
output: any;
|
|
104
|
-
};
|
|
105
|
-
chorusEffect: {
|
|
106
|
-
input: any;
|
|
107
|
-
output: any;
|
|
108
|
-
sendGain: any;
|
|
109
|
-
lfo: any;
|
|
110
|
-
lfoGain: any;
|
|
111
|
-
delayNodes: any[];
|
|
112
|
-
feedbackGains: any[];
|
|
113
|
-
};
|
|
114
117
|
};
|
|
115
118
|
createChannels(audioContext: any): any[];
|
|
116
119
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
@@ -125,7 +128,8 @@ export class MidyGM2 {
|
|
|
125
128
|
instruments: Set<any>;
|
|
126
129
|
timeline: any[];
|
|
127
130
|
};
|
|
128
|
-
|
|
131
|
+
stopChannelNotes(channelNumber: any, velocity: any, stopPedal: any): Promise<void>;
|
|
132
|
+
stopNotes(velocity: any, stopPedal: any): Promise<any[]>;
|
|
129
133
|
start(): Promise<void>;
|
|
130
134
|
stop(): void;
|
|
131
135
|
pause(): void;
|
|
@@ -144,7 +148,7 @@ export class MidyGM2 {
|
|
|
144
148
|
createCombFilter(audioContext: any, input: any, delay: any, feedback: any): any;
|
|
145
149
|
createAllpassFilter(audioContext: any, input: any, delay: any, feedback: any): any;
|
|
146
150
|
generateDistributedArray(center: any, count: any, varianceRatio?: number, randomness?: number): any[];
|
|
147
|
-
createSchroederReverb(audioContext: any,
|
|
151
|
+
createSchroederReverb(audioContext: any, combFeedbacks: any, combDelays: any, allpassFeedbacks: any, allpassDelays: any): {
|
|
148
152
|
input: any;
|
|
149
153
|
output: any;
|
|
150
154
|
};
|
|
@@ -157,14 +161,15 @@ export class MidyGM2 {
|
|
|
157
161
|
delayNodes: any[];
|
|
158
162
|
feedbackGains: any[];
|
|
159
163
|
};
|
|
160
|
-
connectEffects(channel: any, gainNode: any): void;
|
|
161
164
|
cbToRatio(cb: any): number;
|
|
162
165
|
centToHz(cent: any): number;
|
|
163
166
|
calcSemitoneOffset(channel: any): any;
|
|
164
167
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
165
|
-
setVolumeEnvelope(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
+
setVolumeEnvelope(note: any): void;
|
|
169
|
+
setPitch(note: any, semitoneOffset: any): void;
|
|
170
|
+
setFilterNode(channel: any, note: any): void;
|
|
171
|
+
startModulation(channel: any, note: any, startTime: any): void;
|
|
172
|
+
startVibrato(channel: any, note: any, startTime: any): void;
|
|
168
173
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
169
174
|
calcBank(channel: any, channelNumber: any): any;
|
|
170
175
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
@@ -173,15 +178,15 @@ export class MidyGM2 {
|
|
|
173
178
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
174
179
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
175
180
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
176
|
-
handleMIDIMessage(statusByte: any, data1: any, data2: any): void |
|
|
181
|
+
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
177
182
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
178
183
|
handleChannelPressure(channelNumber: any, pressure: any): void;
|
|
179
184
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
180
185
|
setPitchBend(channelNumber: any, pitchBend: any): void;
|
|
181
|
-
handleControlChange(channelNumber: any, controller: any, value: any): void |
|
|
186
|
+
handleControlChange(channelNumber: any, controller: any, value: any): void | Promise<void>;
|
|
182
187
|
setBankMSB(channelNumber: any, msb: any): void;
|
|
183
188
|
updateModulation(channel: any): void;
|
|
184
|
-
|
|
189
|
+
setModulationDepth(channelNumber: any, modulation: any): void;
|
|
185
190
|
setPortamentoTime(channelNumber: any, portamentoTime: any): void;
|
|
186
191
|
setVolume(channelNumber: any, volume: any): void;
|
|
187
192
|
panToGain(pan: any): {
|
|
@@ -214,9 +219,9 @@ export class MidyGM2 {
|
|
|
214
219
|
setCoarseTuning(channelNumber: any, coarseTuning: any): void;
|
|
215
220
|
handleModulationDepthRangeRPN(channelNumber: any): void;
|
|
216
221
|
setModulationDepthRange(channelNumber: any, modulationDepthRange: any): void;
|
|
217
|
-
allSoundOff(channelNumber: any):
|
|
222
|
+
allSoundOff(channelNumber: any): Promise<void>;
|
|
218
223
|
resetAllControllers(channelNumber: any): void;
|
|
219
|
-
allNotesOff(channelNumber: any):
|
|
224
|
+
allNotesOff(channelNumber: any): Promise<void>;
|
|
220
225
|
omniOff(): void;
|
|
221
226
|
omniOn(): void;
|
|
222
227
|
monoOn(): void;
|
|
@@ -256,12 +261,13 @@ export class MidyGM2 {
|
|
|
256
261
|
declare class Note {
|
|
257
262
|
constructor(noteNumber: any, velocity: any, startTime: any, instrumentKey: any);
|
|
258
263
|
bufferSource: any;
|
|
259
|
-
gainNode: any;
|
|
260
264
|
filterNode: any;
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
+
volumeNode: any;
|
|
266
|
+
volumeDepth: any;
|
|
267
|
+
modulationLFO: any;
|
|
268
|
+
modulationDepth: any;
|
|
269
|
+
vibratoLFO: any;
|
|
270
|
+
vibratoDepth: any;
|
|
265
271
|
noteNumber: any;
|
|
266
272
|
velocity: any;
|
|
267
273
|
startTime: any;
|
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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"}
|