@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/esm/midy-GM1.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseMidi } from "./deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js";
|
|
2
|
-
import { parse, SoundFont, } from "./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.
|
|
2
|
+
import { parse, SoundFont, } from "./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.js";
|
|
3
3
|
class Note {
|
|
4
4
|
constructor(noteNumber, velocity, startTime, instrumentKey) {
|
|
5
5
|
Object.defineProperty(this, "bufferSource", {
|
|
@@ -8,25 +8,43 @@ class Note {
|
|
|
8
8
|
writable: true,
|
|
9
9
|
value: void 0
|
|
10
10
|
});
|
|
11
|
-
Object.defineProperty(this, "
|
|
11
|
+
Object.defineProperty(this, "filterNode", {
|
|
12
12
|
enumerable: true,
|
|
13
13
|
configurable: true,
|
|
14
14
|
writable: true,
|
|
15
15
|
value: void 0
|
|
16
16
|
});
|
|
17
|
-
Object.defineProperty(this, "
|
|
17
|
+
Object.defineProperty(this, "volumeNode", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: void 0
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(this, "volumeDepth", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(this, "modulationLFO", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "modulationDepth", {
|
|
18
36
|
enumerable: true,
|
|
19
37
|
configurable: true,
|
|
20
38
|
writable: true,
|
|
21
39
|
value: void 0
|
|
22
40
|
});
|
|
23
|
-
Object.defineProperty(this, "
|
|
41
|
+
Object.defineProperty(this, "vibratoLFO", {
|
|
24
42
|
enumerable: true,
|
|
25
43
|
configurable: true,
|
|
26
44
|
writable: true,
|
|
27
45
|
value: void 0
|
|
28
46
|
});
|
|
29
|
-
Object.defineProperty(this, "
|
|
47
|
+
Object.defineProperty(this, "vibratoDepth", {
|
|
30
48
|
enumerable: true,
|
|
31
49
|
configurable: true,
|
|
32
50
|
writable: true,
|
|
@@ -144,8 +162,8 @@ export class MidyGM1 {
|
|
|
144
162
|
});
|
|
145
163
|
this.audioContext = audioContext;
|
|
146
164
|
this.masterGain = new GainNode(audioContext);
|
|
147
|
-
this.masterGain.connect(audioContext.destination);
|
|
148
165
|
this.channels = this.createChannels(audioContext);
|
|
166
|
+
this.masterGain.connect(audioContext.destination);
|
|
149
167
|
this.GM1SystemOn();
|
|
150
168
|
}
|
|
151
169
|
initSoundFontTable() {
|
|
@@ -189,6 +207,7 @@ export class MidyGM1 {
|
|
|
189
207
|
const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
|
|
190
208
|
gainL.connect(merger, 0, 0);
|
|
191
209
|
gainR.connect(merger, 0, 1);
|
|
210
|
+
merger.connect(this.masterGain);
|
|
192
211
|
return {
|
|
193
212
|
gainL,
|
|
194
213
|
gainR,
|
|
@@ -312,7 +331,7 @@ export class MidyGM1 {
|
|
|
312
331
|
const t = this.audioContext.currentTime + offset;
|
|
313
332
|
queueIndex = await this.scheduleTimelineEvents(t, offset, queueIndex);
|
|
314
333
|
if (this.isPausing) {
|
|
315
|
-
await this.stopNotes();
|
|
334
|
+
await this.stopNotes(0, true);
|
|
316
335
|
this.notePromises = [];
|
|
317
336
|
resolve();
|
|
318
337
|
this.isPausing = false;
|
|
@@ -320,7 +339,7 @@ export class MidyGM1 {
|
|
|
320
339
|
return;
|
|
321
340
|
}
|
|
322
341
|
else if (this.isStopping) {
|
|
323
|
-
await this.stopNotes();
|
|
342
|
+
await this.stopNotes(0, true);
|
|
324
343
|
this.notePromises = [];
|
|
325
344
|
resolve();
|
|
326
345
|
this.isStopping = false;
|
|
@@ -328,7 +347,7 @@ export class MidyGM1 {
|
|
|
328
347
|
return;
|
|
329
348
|
}
|
|
330
349
|
else if (this.isSeeking) {
|
|
331
|
-
this.stopNotes();
|
|
350
|
+
this.stopNotes(0, true);
|
|
332
351
|
this.startTime = this.audioContext.currentTime;
|
|
333
352
|
queueIndex = this.getQueueIndex(this.resumeTime);
|
|
334
353
|
offset = this.resumeTime - this.startTime;
|
|
@@ -409,21 +428,24 @@ export class MidyGM1 {
|
|
|
409
428
|
}
|
|
410
429
|
return { instruments, timeline };
|
|
411
430
|
}
|
|
412
|
-
|
|
431
|
+
async stopChannelNotes(channelNumber, velocity, stopPedal) {
|
|
413
432
|
const now = this.audioContext.currentTime;
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
this.notePromises.push(promise);
|
|
422
|
-
}
|
|
423
|
-
});
|
|
433
|
+
const channel = this.channels[channelNumber];
|
|
434
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
435
|
+
noteList.forEach((note) => {
|
|
436
|
+
if (note) {
|
|
437
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
|
|
438
|
+
this.notePromises.push(promise);
|
|
439
|
+
}
|
|
424
440
|
});
|
|
425
|
-
channel.scheduledNotes.clear();
|
|
426
441
|
});
|
|
442
|
+
channel.scheduledNotes.clear();
|
|
443
|
+
await Promise.all(this.notePromises);
|
|
444
|
+
}
|
|
445
|
+
stopNotes(velocity, stopPedal) {
|
|
446
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
447
|
+
this.stopChannelNotes(i, velocity, stopPedal);
|
|
448
|
+
}
|
|
427
449
|
return Promise.all(this.notePromises);
|
|
428
450
|
}
|
|
429
451
|
async start() {
|
|
@@ -491,10 +513,6 @@ export class MidyGM1 {
|
|
|
491
513
|
}
|
|
492
514
|
return noteList[0];
|
|
493
515
|
}
|
|
494
|
-
connectEffects(channel, gainNode) {
|
|
495
|
-
gainNode.connect(channel.merger);
|
|
496
|
-
merger.connect(this.masterGain);
|
|
497
|
-
}
|
|
498
516
|
cbToRatio(cb) {
|
|
499
517
|
return Math.pow(10, cb / 200);
|
|
500
518
|
}
|
|
@@ -509,27 +527,41 @@ export class MidyGM1 {
|
|
|
509
527
|
return instrumentKey.playbackRate(noteNumber) *
|
|
510
528
|
Math.pow(2, semitoneOffset / 12);
|
|
511
529
|
}
|
|
512
|
-
setVolumeEnvelope(
|
|
513
|
-
const { instrumentKey, startTime
|
|
514
|
-
note.
|
|
515
|
-
|
|
516
|
-
if (volume === 0)
|
|
517
|
-
volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
|
|
518
|
-
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation) *
|
|
519
|
-
volume;
|
|
530
|
+
setVolumeEnvelope(note) {
|
|
531
|
+
const { instrumentKey, startTime } = note;
|
|
532
|
+
note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
|
|
533
|
+
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
|
|
520
534
|
const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
|
|
521
535
|
const volDelay = startTime + instrumentKey.volDelay;
|
|
522
536
|
const volAttack = volDelay + instrumentKey.volAttack;
|
|
523
537
|
const volHold = volAttack + instrumentKey.volHold;
|
|
524
538
|
const volDecay = volHold + instrumentKey.volDecay;
|
|
525
|
-
note.
|
|
539
|
+
note.volumeNode.gain
|
|
526
540
|
.setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
|
|
527
541
|
.exponentialRampToValueAtTime(attackVolume, volAttack)
|
|
528
542
|
.setValueAtTime(attackVolume, volHold)
|
|
529
543
|
.linearRampToValueAtTime(sustainVolume, volDecay);
|
|
530
544
|
}
|
|
531
|
-
|
|
532
|
-
const { instrumentKey,
|
|
545
|
+
setPitch(note, semitoneOffset) {
|
|
546
|
+
const { instrumentKey, noteNumber, startTime } = note;
|
|
547
|
+
const modEnvToPitch = instrumentKey.modEnvToPitch / 100;
|
|
548
|
+
note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
|
|
549
|
+
if (modEnvToPitch === 0)
|
|
550
|
+
return;
|
|
551
|
+
const basePitch = note.bufferSource.playbackRate.value;
|
|
552
|
+
const peekPitch = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset + modEnvToPitch);
|
|
553
|
+
const modDelay = startTime + instrumentKey.modDelay;
|
|
554
|
+
const modAttack = modDelay + instrumentKey.modAttack;
|
|
555
|
+
const modHold = modAttack + instrumentKey.modHold;
|
|
556
|
+
const modDecay = modHold + instrumentKey.modDecay;
|
|
557
|
+
note.bufferSource.playbackRate.value
|
|
558
|
+
.setValueAtTime(basePitch, modDelay)
|
|
559
|
+
.exponentialRampToValueAtTime(peekPitch, modAttack)
|
|
560
|
+
.setValueAtTime(peekPitch, modHold)
|
|
561
|
+
.linearRampToValueAtTime(basePitch, modDecay);
|
|
562
|
+
}
|
|
563
|
+
setFilterNode(channel, note) {
|
|
564
|
+
const { instrumentKey, noteNumber, startTime } = note;
|
|
533
565
|
const softPedalFactor = 1 -
|
|
534
566
|
(0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
|
|
535
567
|
const maxFreq = this.audioContext.sampleRate / 2;
|
|
@@ -538,13 +570,13 @@ export class MidyGM1 {
|
|
|
538
570
|
const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
|
|
539
571
|
const sustainFreq = (baseFreq +
|
|
540
572
|
(peekFreq - baseFreq) * (1 - instrumentKey.modSustain)) * softPedalFactor;
|
|
573
|
+
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
574
|
+
const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
|
|
575
|
+
const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
|
|
541
576
|
const modDelay = startTime + instrumentKey.modDelay;
|
|
542
577
|
const modAttack = modDelay + instrumentKey.modAttack;
|
|
543
578
|
const modHold = modAttack + instrumentKey.modHold;
|
|
544
579
|
const modDecay = modHold + instrumentKey.modDecay;
|
|
545
|
-
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
546
|
-
const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
|
|
547
|
-
const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
|
|
548
580
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
549
581
|
type: "lowpass",
|
|
550
582
|
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
@@ -555,35 +587,49 @@ export class MidyGM1 {
|
|
|
555
587
|
.exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
|
|
556
588
|
.setValueAtTime(adjustedPeekFreq, modHold)
|
|
557
589
|
.linearRampToValueAtTime(adjustedSustainFreq, modDecay);
|
|
558
|
-
note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modEnvToPitch, modDelay);
|
|
559
590
|
}
|
|
560
|
-
startModulation(channel, note,
|
|
591
|
+
startModulation(channel, note, startTime) {
|
|
561
592
|
const { instrumentKey } = note;
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
});
|
|
565
|
-
note.modLFO = new OscillatorNode(this.audioContext, {
|
|
593
|
+
const { modLfoToPitch, modLfoToVolume } = instrumentKey;
|
|
594
|
+
note.modulationLFO = new OscillatorNode(this.audioContext, {
|
|
566
595
|
frequency: this.centToHz(instrumentKey.freqModLFO),
|
|
567
596
|
});
|
|
568
|
-
note.
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
597
|
+
note.filterDepth = new GainNode(this.audioContext, {
|
|
598
|
+
gain: instrumentKey.modLfoToFilterFc,
|
|
599
|
+
});
|
|
600
|
+
const modulationDepth = Math.abs(modLfoToPitch) + channel.modulationDepth;
|
|
601
|
+
const modulationDepthSign = (0 < modLfoToPitch) ? 1 : -1;
|
|
602
|
+
note.modulationDepth = new GainNode(this.audioContext, {
|
|
603
|
+
gain: modulationDepth * modulationDepthSign,
|
|
604
|
+
});
|
|
605
|
+
const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
|
|
606
|
+
const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
|
|
607
|
+
note.volumeDepth = new GainNode(this.audioContext, {
|
|
608
|
+
gain: volumeDepth * volumeDepthSign,
|
|
609
|
+
});
|
|
610
|
+
note.modulationLFO.start(startTime + instrumentKey.delayModLFO);
|
|
611
|
+
note.modulationLFO.connect(note.filterDepth);
|
|
612
|
+
note.filterDepth.connect(note.filterNode.frequency);
|
|
613
|
+
note.modulationLFO.connect(note.modulationDepth);
|
|
614
|
+
note.modulationDepth.connect(note.bufferSource.detune);
|
|
615
|
+
note.modulationLFO.connect(note.volumeDepth);
|
|
616
|
+
note.volumeDepth.connect(note.volumeNode.gain);
|
|
573
617
|
}
|
|
574
618
|
async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
|
|
575
619
|
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
576
620
|
const note = new Note(noteNumber, velocity, startTime, instrumentKey);
|
|
577
621
|
note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
|
|
578
|
-
|
|
579
|
-
this.setVolumeEnvelope(
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
622
|
+
this.setFilterNode(channel, note);
|
|
623
|
+
this.setVolumeEnvelope(note);
|
|
624
|
+
if (0 < channel.modulationDepth) {
|
|
625
|
+
this.setPitch(note, semitoneOffset);
|
|
626
|
+
this.startModulation(channel, note, startTime);
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
|
|
584
630
|
}
|
|
585
631
|
note.bufferSource.connect(note.filterNode);
|
|
586
|
-
note.filterNode.connect(note.
|
|
632
|
+
note.filterNode.connect(note.volumeNode);
|
|
587
633
|
note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
|
|
588
634
|
return note;
|
|
589
635
|
}
|
|
@@ -599,7 +645,8 @@ export class MidyGM1 {
|
|
|
599
645
|
if (!instrumentKey)
|
|
600
646
|
return;
|
|
601
647
|
const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
|
|
602
|
-
|
|
648
|
+
note.volumeNode.connect(channel.gainL);
|
|
649
|
+
note.volumeNode.connect(channel.gainR);
|
|
603
650
|
const scheduledNotes = channel.scheduledNotes;
|
|
604
651
|
if (scheduledNotes.has(noteNumber)) {
|
|
605
652
|
scheduledNotes.get(noteNumber).push(note);
|
|
@@ -628,17 +675,14 @@ export class MidyGM1 {
|
|
|
628
675
|
const velocityRate = (velocity + 127) / 127;
|
|
629
676
|
const volEndTime = stopTime +
|
|
630
677
|
note.instrumentKey.volRelease * velocityRate;
|
|
631
|
-
note.
|
|
678
|
+
note.volumeNode.gain
|
|
632
679
|
.cancelScheduledValues(stopTime)
|
|
633
680
|
.linearRampToValueAtTime(0, volEndTime);
|
|
634
|
-
const
|
|
635
|
-
const baseFreq = this.centToHz(note.instrumentKey.initialFilterFc);
|
|
636
|
-
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
637
|
-
const modEndTime = stopTime +
|
|
681
|
+
const modRelease = stopTime +
|
|
638
682
|
note.instrumentKey.modRelease * velocityRate;
|
|
639
683
|
note.filterNode.frequency
|
|
640
684
|
.cancelScheduledValues(stopTime)
|
|
641
|
-
.linearRampToValueAtTime(
|
|
685
|
+
.linearRampToValueAtTime(0, modRelease);
|
|
642
686
|
note.ending = true;
|
|
643
687
|
this.scheduleTask(() => {
|
|
644
688
|
note.bufferSource.loop = false;
|
|
@@ -647,15 +691,17 @@ export class MidyGM1 {
|
|
|
647
691
|
note.bufferSource.onended = () => {
|
|
648
692
|
scheduledNotes[i] = null;
|
|
649
693
|
note.bufferSource.disconnect();
|
|
694
|
+
note.volumeNode.disconnect();
|
|
650
695
|
note.filterNode.disconnect();
|
|
651
|
-
note.
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
696
|
+
if (note.volumeDepth)
|
|
697
|
+
note.volumeDepth.disconnect();
|
|
698
|
+
if (note.modulationDepth)
|
|
699
|
+
note.modulationDepth.disconnect();
|
|
700
|
+
if (note.modulationLFO)
|
|
701
|
+
note.modulationLFO.stop();
|
|
656
702
|
resolve();
|
|
657
703
|
};
|
|
658
|
-
bufferSource.stop(volEndTime);
|
|
704
|
+
note.bufferSource.stop(volEndTime);
|
|
659
705
|
});
|
|
660
706
|
}
|
|
661
707
|
}
|
|
@@ -668,10 +714,10 @@ export class MidyGM1 {
|
|
|
668
714
|
const channel = this.channels[channelNumber];
|
|
669
715
|
const promises = [];
|
|
670
716
|
channel.sustainPedal = false;
|
|
671
|
-
channel.scheduledNotes.forEach((
|
|
672
|
-
|
|
673
|
-
if (
|
|
674
|
-
const { noteNumber } =
|
|
717
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
718
|
+
noteList.forEach((note) => {
|
|
719
|
+
if (note) {
|
|
720
|
+
const { noteNumber } = note;
|
|
675
721
|
const promise = this.releaseNote(channelNumber, noteNumber, velocity);
|
|
676
722
|
promises.push(promise);
|
|
677
723
|
}
|
|
@@ -702,13 +748,13 @@ export class MidyGM1 {
|
|
|
702
748
|
channel.program = program;
|
|
703
749
|
}
|
|
704
750
|
handlePitchBendMessage(channelNumber, lsb, msb) {
|
|
705
|
-
const pitchBend = msb * 128 + lsb;
|
|
751
|
+
const pitchBend = msb * 128 + lsb - 8192;
|
|
706
752
|
this.setPitchBend(channelNumber, pitchBend);
|
|
707
753
|
}
|
|
708
754
|
setPitchBend(channelNumber, pitchBend) {
|
|
709
755
|
const channel = this.channels[channelNumber];
|
|
710
756
|
const prevPitchBend = channel.pitchBend;
|
|
711
|
-
channel.pitchBend =
|
|
757
|
+
channel.pitchBend = pitchBend / 8192;
|
|
712
758
|
const detuneChange = (channel.pitchBend - prevPitchBend) *
|
|
713
759
|
channel.pitchBendRange * 100;
|
|
714
760
|
this.updateDetune(channel, detuneChange);
|
|
@@ -716,7 +762,7 @@ export class MidyGM1 {
|
|
|
716
762
|
handleControlChange(channelNumber, controller, value) {
|
|
717
763
|
switch (controller) {
|
|
718
764
|
case 1:
|
|
719
|
-
return this.
|
|
765
|
+
return this.setModulationDepth(channelNumber, value);
|
|
720
766
|
case 6:
|
|
721
767
|
return this.dataEntryMSB(channelNumber, value);
|
|
722
768
|
case 7:
|
|
@@ -747,18 +793,19 @@ export class MidyGM1 {
|
|
|
747
793
|
const now = this.audioContext.currentTime;
|
|
748
794
|
const activeNotes = this.getActiveNotes(channel, now);
|
|
749
795
|
activeNotes.forEach((activeNote) => {
|
|
750
|
-
if (activeNote.
|
|
751
|
-
|
|
752
|
-
gainNode.gain.setValueAtTime(this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation), now);
|
|
796
|
+
if (activeNote.modulationDepth) {
|
|
797
|
+
activeNote.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
|
|
753
798
|
}
|
|
754
799
|
else {
|
|
800
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
801
|
+
this.setPitch(activeNote, semitoneOffset);
|
|
755
802
|
this.startModulation(channel, activeNote, now);
|
|
756
803
|
}
|
|
757
804
|
});
|
|
758
805
|
}
|
|
759
|
-
|
|
806
|
+
setModulationDepth(channelNumber, modulation) {
|
|
760
807
|
const channel = this.channels[channelNumber];
|
|
761
|
-
channel.
|
|
808
|
+
channel.modulationDepth = (modulation / 127) * channel.modulationDepthRange;
|
|
762
809
|
this.updateModulation(channel);
|
|
763
810
|
}
|
|
764
811
|
setVolume(channelNumber, volume) {
|
|
@@ -910,37 +957,13 @@ export class MidyGM1 {
|
|
|
910
957
|
this.updateDetune(channel, detuneChange);
|
|
911
958
|
}
|
|
912
959
|
allSoundOff(channelNumber) {
|
|
913
|
-
|
|
914
|
-
const channel = this.channels[channelNumber];
|
|
915
|
-
const velocity = 0;
|
|
916
|
-
const stopPedal = true;
|
|
917
|
-
const promises = [];
|
|
918
|
-
channel.scheduledNotes.forEach((noteList) => {
|
|
919
|
-
const activeNote = this.getActiveNote(noteList, now);
|
|
920
|
-
if (activeNote) {
|
|
921
|
-
const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
|
|
922
|
-
promises.push(notePromise);
|
|
923
|
-
}
|
|
924
|
-
});
|
|
925
|
-
return promises;
|
|
960
|
+
return this.stopChannelNotes(channelNumber, 0, true);
|
|
926
961
|
}
|
|
927
962
|
resetAllControllers(channelNumber) {
|
|
928
963
|
Object.assign(this.channels[channelNumber], this.effectSettings);
|
|
929
964
|
}
|
|
930
965
|
allNotesOff(channelNumber) {
|
|
931
|
-
|
|
932
|
-
const channel = this.channels[channelNumber];
|
|
933
|
-
const velocity = 0;
|
|
934
|
-
const stopPedal = false;
|
|
935
|
-
const promises = [];
|
|
936
|
-
channel.scheduledNotes.forEach((noteList) => {
|
|
937
|
-
const activeNote = this.getActiveNote(noteList, now);
|
|
938
|
-
if (activeNote) {
|
|
939
|
-
const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
|
|
940
|
-
promises.push(notePromise);
|
|
941
|
-
}
|
|
942
|
-
});
|
|
943
|
-
return promises;
|
|
966
|
+
return this.stopChannelNotes(channelNumber, 0, false);
|
|
944
967
|
}
|
|
945
968
|
handleUniversalNonRealTimeExclusiveMessage(data) {
|
|
946
969
|
switch (data[2]) {
|
|
@@ -1035,7 +1058,7 @@ Object.defineProperty(MidyGM1, "channelSettings", {
|
|
|
1035
1058
|
pitchBend: 0,
|
|
1036
1059
|
fineTuning: 0, // cb
|
|
1037
1060
|
coarseTuning: 0, // cb
|
|
1038
|
-
modulationDepthRange:
|
|
1061
|
+
modulationDepthRange: 50, // cent
|
|
1039
1062
|
}
|
|
1040
1063
|
});
|
|
1041
1064
|
Object.defineProperty(MidyGM1, "effectSettings", {
|
|
@@ -1044,7 +1067,7 @@ Object.defineProperty(MidyGM1, "effectSettings", {
|
|
|
1044
1067
|
writable: true,
|
|
1045
1068
|
value: {
|
|
1046
1069
|
expression: 1,
|
|
1047
|
-
|
|
1070
|
+
modulationDepth: 0,
|
|
1048
1071
|
sustainPedal: false,
|
|
1049
1072
|
rpnMSB: 127,
|
|
1050
1073
|
rpnLSB: 127,
|
package/esm/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/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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"}
|