@marmooo/midy 0.1.0 → 0.1.1
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-GM2.d.ts +18 -8
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +141 -69
- package/esm/midy.d.ts +18 -8
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +141 -69
- package/package.json +1 -1
- package/script/midy-GM2.d.ts +18 -8
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +141 -69
- package/script/midy.d.ts +18 -8
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +141 -69
package/script/midy-GM2.js
CHANGED
|
@@ -85,7 +85,7 @@ class MidyGM2 {
|
|
|
85
85
|
writable: true,
|
|
86
86
|
value: {
|
|
87
87
|
time: this.getReverbTime(64),
|
|
88
|
-
feedback: 0.
|
|
88
|
+
feedback: 0.25,
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
91
|
Object.defineProperty(this, "chorus", {
|
|
@@ -93,10 +93,11 @@ class MidyGM2 {
|
|
|
93
93
|
configurable: true,
|
|
94
94
|
writable: true,
|
|
95
95
|
value: {
|
|
96
|
-
modRate: 3
|
|
97
|
-
modDepth: (
|
|
98
|
-
feedback: 8
|
|
99
|
-
sendToReverb: 0
|
|
96
|
+
modRate: this.getChorusModRate(3),
|
|
97
|
+
modDepth: this.getChorusModDepth(19),
|
|
98
|
+
feedback: this.getChorusFeedback(8),
|
|
99
|
+
sendToReverb: this.getChorusSendToReverb(0),
|
|
100
|
+
delayTimes: this.generateDistributedArray(0.02, 2, 0.5),
|
|
100
101
|
}
|
|
101
102
|
});
|
|
102
103
|
Object.defineProperty(this, "mono", {
|
|
@@ -691,9 +692,7 @@ class MidyGM2 {
|
|
|
691
692
|
createSchroederReverb(audioContext, combDelays, combFeedbacks, allpassDelays, allpassFeedbacks) {
|
|
692
693
|
const input = new GainNode(audioContext);
|
|
693
694
|
const output = new GainNode(audioContext);
|
|
694
|
-
const mergerGain = new GainNode(audioContext
|
|
695
|
-
gain: 1 / (combDelays.length * 2),
|
|
696
|
-
});
|
|
695
|
+
const mergerGain = new GainNode(audioContext);
|
|
697
696
|
for (let i = 0; i < combDelays.length; i++) {
|
|
698
697
|
const comb = this.createCombFilter(audioContext, input, combDelays[i], combFeedbacks[i]);
|
|
699
698
|
comb.connect(mergerGain);
|
|
@@ -706,60 +705,62 @@ class MidyGM2 {
|
|
|
706
705
|
allpasses.at(-1).connect(output);
|
|
707
706
|
return { input, output };
|
|
708
707
|
}
|
|
709
|
-
createChorusEffect(audioContext
|
|
710
|
-
const
|
|
711
|
-
const lfo = new OscillatorNode(audioContext, { frequency: chorusRate });
|
|
712
|
-
const lfoGain = new GainNode(audioContext, { gain: chorusDepth });
|
|
708
|
+
createChorusEffect(audioContext) {
|
|
709
|
+
const input = new GainNode(audioContext);
|
|
713
710
|
const output = new GainNode(audioContext);
|
|
714
|
-
const
|
|
711
|
+
const sendGain = new GainNode(audioContext);
|
|
712
|
+
const lfo = new OscillatorNode(audioContext, {
|
|
713
|
+
frequency: this.chorus.modRate,
|
|
714
|
+
});
|
|
715
|
+
const lfoGain = new GainNode(audioContext, {
|
|
716
|
+
gain: this.chorus.modDepth / 2,
|
|
717
|
+
});
|
|
718
|
+
const delayTimes = this.chorus.delayTimes;
|
|
715
719
|
const delayNodes = [];
|
|
716
|
-
const
|
|
717
|
-
for (let i = 0; i <
|
|
718
|
-
const
|
|
719
|
-
const delayTime = (i + 1) * delay + randomDelayFactor;
|
|
720
|
+
const feedbackGains = [];
|
|
721
|
+
for (let i = 0; i < delayTimes.length; i++) {
|
|
722
|
+
const delayTime = delayTimes[i];
|
|
720
723
|
const delayNode = new DelayNode(audioContext, {
|
|
721
|
-
maxDelayTime: delayTime
|
|
724
|
+
maxDelayTime: 0.1, // generally, 5ms < delayTime < 50ms
|
|
725
|
+
delayTime,
|
|
726
|
+
});
|
|
727
|
+
const feedbackGain = new GainNode(audioContext, {
|
|
728
|
+
gain: this.chorus.feedback,
|
|
722
729
|
});
|
|
723
|
-
const chorusGain = new GainNode(audioContext, { gain: baseGain });
|
|
724
730
|
delayNodes.push(delayNode);
|
|
725
|
-
|
|
731
|
+
feedbackGains.push(feedbackGain);
|
|
732
|
+
input.connect(delayNode);
|
|
726
733
|
lfoGain.connect(delayNode.delayTime);
|
|
727
|
-
delayNode.connect(
|
|
728
|
-
|
|
734
|
+
delayNode.connect(feedbackGain);
|
|
735
|
+
feedbackGain.connect(delayNode);
|
|
736
|
+
delayNode.connect(output);
|
|
729
737
|
}
|
|
738
|
+
output.connect(sendGain);
|
|
730
739
|
lfo.connect(lfoGain);
|
|
731
740
|
lfo.start();
|
|
732
741
|
return {
|
|
742
|
+
input,
|
|
743
|
+
output,
|
|
744
|
+
sendGain,
|
|
733
745
|
lfo,
|
|
734
746
|
lfoGain,
|
|
735
747
|
delayNodes,
|
|
736
|
-
|
|
737
|
-
output,
|
|
748
|
+
feedbackGains,
|
|
738
749
|
};
|
|
739
750
|
}
|
|
740
751
|
connectEffects(channel, gainNode) {
|
|
741
752
|
gainNode.connect(channel.merger);
|
|
742
753
|
channel.merger.connect(this.masterGain);
|
|
743
|
-
if (channel.reverbSendLevel
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
channel.merger.connect(delayNode);
|
|
747
|
-
});
|
|
748
|
-
channel.chorusEffect.output.connect(this.masterGain);
|
|
749
|
-
}
|
|
754
|
+
if (0 < channel.reverbSendLevel) {
|
|
755
|
+
channel.merger.connect(channel.reverbEffect.input);
|
|
756
|
+
channel.reverbEffect.output.connect(this.masterGain);
|
|
750
757
|
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
channel.chorusEffect.delayNodes.forEach((delayNode) => {
|
|
758
|
-
channel.merger.connect(delayNode);
|
|
759
|
-
});
|
|
760
|
-
channel.merger.connect(channel.reverbEffect.input);
|
|
761
|
-
channel.reverbEffect.output.connect(this.masterGain);
|
|
762
|
-
}
|
|
758
|
+
if (0 < channel.chorusSendLevel) {
|
|
759
|
+
channel.merger.connect(channel.chorusEffect.input);
|
|
760
|
+
channel.reverbEffect.output.connect(this.masterGain);
|
|
761
|
+
}
|
|
762
|
+
if (0 < this.chorus.sendToReverb) {
|
|
763
|
+
channel.chorusEffect.sendGain.connect(channel.reverbEffect.input);
|
|
763
764
|
}
|
|
764
765
|
}
|
|
765
766
|
cbToRatio(cb) {
|
|
@@ -1173,9 +1174,12 @@ class MidyGM2 {
|
|
|
1173
1174
|
reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
|
|
1174
1175
|
}
|
|
1175
1176
|
setChorusSendLevel(channelNumber, chorusSendLevel) {
|
|
1177
|
+
const now = this.audioContext.currentTime;
|
|
1176
1178
|
const channel = this.channels[channelNumber];
|
|
1179
|
+
const chorusEffect = channel.chorusEffect;
|
|
1177
1180
|
channel.chorusSendLevel = chorusSendLevel / 127;
|
|
1178
|
-
|
|
1181
|
+
chorusEffect.output.gain.cancelScheduledValues(now);
|
|
1182
|
+
chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
|
|
1179
1183
|
}
|
|
1180
1184
|
setSostenutoPedal(channelNumber, value) {
|
|
1181
1185
|
const isOn = value >= 64;
|
|
@@ -1407,7 +1411,7 @@ class MidyGM2 {
|
|
|
1407
1411
|
case 4: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca25.pdf
|
|
1408
1412
|
return this.handleMasterCoarseTuningSysEx(data);
|
|
1409
1413
|
case 5:
|
|
1410
|
-
return this.
|
|
1414
|
+
return this.handleGlobalParameterControlSysEx(data);
|
|
1411
1415
|
default:
|
|
1412
1416
|
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1413
1417
|
}
|
|
@@ -1484,13 +1488,13 @@ class MidyGM2 {
|
|
|
1484
1488
|
this.masterCoarseTuning = coarseTuning - 64;
|
|
1485
1489
|
}
|
|
1486
1490
|
}
|
|
1487
|
-
|
|
1488
|
-
if (data[
|
|
1489
|
-
switch (data[
|
|
1491
|
+
handleGlobalParameterControlSysEx(data) {
|
|
1492
|
+
if (data[7] === 1) {
|
|
1493
|
+
switch (data[8]) {
|
|
1490
1494
|
case 1:
|
|
1491
|
-
return this.
|
|
1495
|
+
return this.handleReverbParameterSysEx(data);
|
|
1492
1496
|
case 2:
|
|
1493
|
-
return this.
|
|
1497
|
+
return this.handleChorusParameterSysEx(data);
|
|
1494
1498
|
default:
|
|
1495
1499
|
console.warn(`Unsupported Global Parameter Control Message: ${data}`);
|
|
1496
1500
|
}
|
|
@@ -1499,12 +1503,12 @@ class MidyGM2 {
|
|
|
1499
1503
|
console.warn(`Unsupported Global Parameter Control Message: ${data}`);
|
|
1500
1504
|
}
|
|
1501
1505
|
}
|
|
1502
|
-
|
|
1503
|
-
switch (data[
|
|
1506
|
+
handleReverbParameterSysEx(data) {
|
|
1507
|
+
switch (data[9]) {
|
|
1504
1508
|
case 0:
|
|
1505
|
-
return this.setReverbType(data[
|
|
1509
|
+
return this.setReverbType(data[10]);
|
|
1506
1510
|
case 1:
|
|
1507
|
-
return this.setReverbTime(data[
|
|
1511
|
+
return this.setReverbTime(data[10]);
|
|
1508
1512
|
}
|
|
1509
1513
|
}
|
|
1510
1514
|
setReverbType(type) {
|
|
@@ -1564,41 +1568,109 @@ class MidyGM2 {
|
|
|
1564
1568
|
// RT60 = -3 * delay / Math.log10(feedback)
|
|
1565
1569
|
// feedback = Math.pow(10, -3 * delay / RT60)
|
|
1566
1570
|
// delay estimation using ideal feedback
|
|
1567
|
-
//
|
|
1568
|
-
//
|
|
1569
|
-
// It
|
|
1571
|
+
// The structure of a concert hall is complex,
|
|
1572
|
+
// so estimates based on mean free path are unstable.
|
|
1573
|
+
// It is easier to determine the delay based on ideal feedback.
|
|
1574
|
+
// The average sound absorption coefficient
|
|
1575
|
+
// suitable for playing musical instruments is 0.18 to 0.28.
|
|
1570
1576
|
// delay = -RT60 * Math.log10(feedback) / 3
|
|
1571
1577
|
calcDelay(rt60, feedback) {
|
|
1572
1578
|
return -rt60 * Math.log10(feedback) / 3;
|
|
1573
1579
|
}
|
|
1574
|
-
|
|
1575
|
-
switch (data[
|
|
1580
|
+
handleChorusParameterSysEx(data) {
|
|
1581
|
+
switch (data[9]) {
|
|
1576
1582
|
case 0:
|
|
1577
|
-
return this.setChorusType(data[
|
|
1583
|
+
return this.setChorusType(data[10]);
|
|
1578
1584
|
case 1:
|
|
1579
|
-
return this.setChorusModRate(data[
|
|
1585
|
+
return this.setChorusModRate(data[10]);
|
|
1580
1586
|
case 2:
|
|
1581
|
-
return this.setChorusModDepth(data[
|
|
1587
|
+
return this.setChorusModDepth(data[10]);
|
|
1582
1588
|
case 3:
|
|
1583
|
-
return this.setChorusFeedback(data[
|
|
1589
|
+
return this.setChorusFeedback(data[10]);
|
|
1584
1590
|
case 4:
|
|
1585
|
-
return this.setChorusSendToReverb(data[
|
|
1591
|
+
return this.setChorusSendToReverb(data[10]);
|
|
1586
1592
|
}
|
|
1587
1593
|
}
|
|
1588
1594
|
setChorusType(type) {
|
|
1589
|
-
|
|
1595
|
+
switch (type) {
|
|
1596
|
+
case 0:
|
|
1597
|
+
return this.setChorusParameter(3, 5, 0, 0);
|
|
1598
|
+
case 1:
|
|
1599
|
+
return this.setChorusParameter(9, 19, 5, 0);
|
|
1600
|
+
case 2:
|
|
1601
|
+
return this.setChorusParameter(3, 19, 8, 0);
|
|
1602
|
+
case 3:
|
|
1603
|
+
return this.setChorusParameter(9, 16, 16, 0);
|
|
1604
|
+
case 4:
|
|
1605
|
+
return this.setChorusParameter(2, 24, 64, 0);
|
|
1606
|
+
case 5:
|
|
1607
|
+
return this.setChorusParameter(1, 5, 112, 0);
|
|
1608
|
+
default:
|
|
1609
|
+
console.warn(`Unsupported Chorus Type: ${type}`);
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
setChorusParameter(modRate, modDepth, feedback, sendToReverb) {
|
|
1613
|
+
this.setChorusModRate(modRate);
|
|
1614
|
+
this.setChorusModDepth(modDepth);
|
|
1615
|
+
this.setChorusFeedback(feedback);
|
|
1616
|
+
this.setChorusSendToReverb(sendToReverb);
|
|
1590
1617
|
}
|
|
1591
1618
|
setChorusModRate(value) {
|
|
1592
|
-
|
|
1619
|
+
const now = this.audioContext.currentTime;
|
|
1620
|
+
const modRate = this.getChorusModRate(value);
|
|
1621
|
+
this.chorus.modRate = modRate;
|
|
1622
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1623
|
+
const lfo = this.channels[i].chorusEffect.lfo;
|
|
1624
|
+
lfo.frequency.setValueAtTime(modRate, now);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
getChorusModRate(value) {
|
|
1628
|
+
return value * 0.122; // Hz
|
|
1593
1629
|
}
|
|
1594
1630
|
setChorusModDepth(value) {
|
|
1595
|
-
|
|
1631
|
+
const now = this.audioContext.currentTime;
|
|
1632
|
+
const modDepth = this.getChorusModDepth(value);
|
|
1633
|
+
this.chorus.modDepth = modDepth;
|
|
1634
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1635
|
+
const chorusEffect = this.channels[i].chorusEffect;
|
|
1636
|
+
chorusEffect.lfoGain.gain
|
|
1637
|
+
.cancelScheduledValues(now)
|
|
1638
|
+
.setValueAtTime(modDepth / 2, now);
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
getChorusModDepth(value) {
|
|
1642
|
+
return (value + 1) / 3200; // second
|
|
1596
1643
|
}
|
|
1597
1644
|
setChorusFeedback(value) {
|
|
1598
|
-
|
|
1645
|
+
const now = this.audioContext.currentTime;
|
|
1646
|
+
const feedback = this.getChorusFeedback(value);
|
|
1647
|
+
this.chorus.feedback = feedback;
|
|
1648
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1649
|
+
const chorusEffect = this.channels[i].chorusEffect;
|
|
1650
|
+
for (let j = 0; j < chorusEffect.feedbackGains.length; j++) {
|
|
1651
|
+
const feedbackGain = chorusEffect.feedbackGains[j];
|
|
1652
|
+
feedbackGain.gain
|
|
1653
|
+
.cancelScheduledValues(now)
|
|
1654
|
+
.setValueAtTime(feedback, now);
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
getChorusFeedback(value) {
|
|
1659
|
+
return value * 0.00763;
|
|
1599
1660
|
}
|
|
1600
1661
|
setChorusSendToReverb(value) {
|
|
1601
|
-
|
|
1662
|
+
const now = this.audioContext.currentTime;
|
|
1663
|
+
const sendToReverb = this.getChorusSendToReverb(value);
|
|
1664
|
+
this.chorus.sendToReverb = sendToReverb;
|
|
1665
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1666
|
+
const chorusEffect = this.channels[i].chorusEffect;
|
|
1667
|
+
chorusEffect.sendGain.gain
|
|
1668
|
+
.cancelScheduledValues(now)
|
|
1669
|
+
.setValueAtTime(sendToReverb, now);
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
getChorusSendToReverb(value) {
|
|
1673
|
+
return value * 0.00787;
|
|
1602
1674
|
}
|
|
1603
1675
|
handleExclusiveMessage(data) {
|
|
1604
1676
|
console.warn(`Unsupported Exclusive Message: ${data}`);
|
package/script/midy.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export class Midy {
|
|
|
59
59
|
modDepth: number;
|
|
60
60
|
feedback: number;
|
|
61
61
|
sendToReverb: number;
|
|
62
|
+
delayTimes: any[];
|
|
62
63
|
};
|
|
63
64
|
mono: boolean;
|
|
64
65
|
omni: boolean;
|
|
@@ -105,11 +106,13 @@ export class Midy {
|
|
|
105
106
|
output: any;
|
|
106
107
|
};
|
|
107
108
|
chorusEffect: {
|
|
109
|
+
input: any;
|
|
110
|
+
output: any;
|
|
111
|
+
sendGain: any;
|
|
108
112
|
lfo: any;
|
|
109
113
|
lfoGain: any;
|
|
110
114
|
delayNodes: any[];
|
|
111
|
-
|
|
112
|
-
output: any;
|
|
115
|
+
feedbackGains: any[];
|
|
113
116
|
};
|
|
114
117
|
};
|
|
115
118
|
createChannels(audioContext: any): any[];
|
|
@@ -148,12 +151,14 @@ export class Midy {
|
|
|
148
151
|
input: any;
|
|
149
152
|
output: any;
|
|
150
153
|
};
|
|
151
|
-
createChorusEffect(audioContext: any
|
|
154
|
+
createChorusEffect(audioContext: any): {
|
|
155
|
+
input: any;
|
|
156
|
+
output: any;
|
|
157
|
+
sendGain: any;
|
|
152
158
|
lfo: any;
|
|
153
159
|
lfoGain: any;
|
|
154
160
|
delayNodes: any[];
|
|
155
|
-
|
|
156
|
-
output: any;
|
|
161
|
+
feedbackGains: any[];
|
|
157
162
|
};
|
|
158
163
|
connectEffects(channel: any, gainNode: any): void;
|
|
159
164
|
cbToRatio(cb: any): number;
|
|
@@ -236,19 +241,24 @@ export class Midy {
|
|
|
236
241
|
setMasterFineTuning(fineTuning: any): void;
|
|
237
242
|
handleMasterCoarseTuningSysEx(data: any): void;
|
|
238
243
|
setMasterCoarseTuning(coarseTuning: any): void;
|
|
239
|
-
|
|
240
|
-
|
|
244
|
+
handleGlobalParameterControlSysEx(data: any): void;
|
|
245
|
+
handleReverbParameterSysEx(data: any): void;
|
|
241
246
|
setReverbType(type: any): void;
|
|
242
247
|
getReverbTimeFromType(type: any): number | undefined;
|
|
243
248
|
setReverbTime(value: any): void;
|
|
244
249
|
getReverbTime(value: any): number;
|
|
245
250
|
calcDelay(rt60: any, feedback: any): number;
|
|
246
|
-
|
|
251
|
+
handleChorusParameterSysEx(data: any): void;
|
|
247
252
|
setChorusType(type: any): void;
|
|
253
|
+
setChorusParameter(modRate: any, modDepth: any, feedback: any, sendToReverb: any): void;
|
|
248
254
|
setChorusModRate(value: any): void;
|
|
255
|
+
getChorusModRate(value: any): number;
|
|
249
256
|
setChorusModDepth(value: any): void;
|
|
257
|
+
getChorusModDepth(value: any): number;
|
|
250
258
|
setChorusFeedback(value: any): void;
|
|
259
|
+
getChorusFeedback(value: any): number;
|
|
251
260
|
setChorusSendToReverb(value: any): void;
|
|
261
|
+
getChorusSendToReverb(value: any): number;
|
|
252
262
|
handleExclusiveMessage(data: any): void;
|
|
253
263
|
handleSysEx(data: any): void;
|
|
254
264
|
scheduleTask(callback: any, startTime: any): Promise<any>;
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAuBA;
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
|