@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/esm/midy.js
CHANGED
|
@@ -82,7 +82,7 @@ export class Midy {
|
|
|
82
82
|
writable: true,
|
|
83
83
|
value: {
|
|
84
84
|
time: this.getReverbTime(64),
|
|
85
|
-
feedback: 0.
|
|
85
|
+
feedback: 0.25,
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
88
|
Object.defineProperty(this, "chorus", {
|
|
@@ -90,10 +90,11 @@ export class Midy {
|
|
|
90
90
|
configurable: true,
|
|
91
91
|
writable: true,
|
|
92
92
|
value: {
|
|
93
|
-
modRate: 3
|
|
94
|
-
modDepth: (
|
|
95
|
-
feedback: 8
|
|
96
|
-
sendToReverb: 0
|
|
93
|
+
modRate: this.getChorusModRate(3),
|
|
94
|
+
modDepth: this.getChorusModDepth(19),
|
|
95
|
+
feedback: this.getChorusFeedback(8),
|
|
96
|
+
sendToReverb: this.getChorusSendToReverb(0),
|
|
97
|
+
delayTimes: this.generateDistributedArray(0.02, 2, 0.5),
|
|
97
98
|
}
|
|
98
99
|
});
|
|
99
100
|
Object.defineProperty(this, "mono", {
|
|
@@ -694,9 +695,7 @@ export class Midy {
|
|
|
694
695
|
createSchroederReverb(audioContext, combDelays, combFeedbacks, allpassDelays, allpassFeedbacks) {
|
|
695
696
|
const input = new GainNode(audioContext);
|
|
696
697
|
const output = new GainNode(audioContext);
|
|
697
|
-
const mergerGain = new GainNode(audioContext
|
|
698
|
-
gain: 1 / (combDelays.length * 2),
|
|
699
|
-
});
|
|
698
|
+
const mergerGain = new GainNode(audioContext);
|
|
700
699
|
for (let i = 0; i < combDelays.length; i++) {
|
|
701
700
|
const comb = this.createCombFilter(audioContext, input, combDelays[i], combFeedbacks[i]);
|
|
702
701
|
comb.connect(mergerGain);
|
|
@@ -709,60 +708,62 @@ export class Midy {
|
|
|
709
708
|
allpasses.at(-1).connect(output);
|
|
710
709
|
return { input, output };
|
|
711
710
|
}
|
|
712
|
-
createChorusEffect(audioContext
|
|
713
|
-
const
|
|
714
|
-
const lfo = new OscillatorNode(audioContext, { frequency: chorusRate });
|
|
715
|
-
const lfoGain = new GainNode(audioContext, { gain: chorusDepth });
|
|
711
|
+
createChorusEffect(audioContext) {
|
|
712
|
+
const input = new GainNode(audioContext);
|
|
716
713
|
const output = new GainNode(audioContext);
|
|
717
|
-
const
|
|
714
|
+
const sendGain = new GainNode(audioContext);
|
|
715
|
+
const lfo = new OscillatorNode(audioContext, {
|
|
716
|
+
frequency: this.chorus.modRate,
|
|
717
|
+
});
|
|
718
|
+
const lfoGain = new GainNode(audioContext, {
|
|
719
|
+
gain: this.chorus.modDepth / 2,
|
|
720
|
+
});
|
|
721
|
+
const delayTimes = this.chorus.delayTimes;
|
|
718
722
|
const delayNodes = [];
|
|
719
|
-
const
|
|
720
|
-
for (let i = 0; i <
|
|
721
|
-
const
|
|
722
|
-
const delayTime = (i + 1) * delay + randomDelayFactor;
|
|
723
|
+
const feedbackGains = [];
|
|
724
|
+
for (let i = 0; i < delayTimes.length; i++) {
|
|
725
|
+
const delayTime = delayTimes[i];
|
|
723
726
|
const delayNode = new DelayNode(audioContext, {
|
|
724
|
-
maxDelayTime: delayTime
|
|
727
|
+
maxDelayTime: 0.1, // generally, 5ms < delayTime < 50ms
|
|
728
|
+
delayTime,
|
|
729
|
+
});
|
|
730
|
+
const feedbackGain = new GainNode(audioContext, {
|
|
731
|
+
gain: this.chorus.feedback,
|
|
725
732
|
});
|
|
726
|
-
const chorusGain = new GainNode(audioContext, { gain: baseGain });
|
|
727
733
|
delayNodes.push(delayNode);
|
|
728
|
-
|
|
734
|
+
feedbackGains.push(feedbackGain);
|
|
735
|
+
input.connect(delayNode);
|
|
729
736
|
lfoGain.connect(delayNode.delayTime);
|
|
730
|
-
delayNode.connect(
|
|
731
|
-
|
|
737
|
+
delayNode.connect(feedbackGain);
|
|
738
|
+
feedbackGain.connect(delayNode);
|
|
739
|
+
delayNode.connect(output);
|
|
732
740
|
}
|
|
741
|
+
output.connect(sendGain);
|
|
733
742
|
lfo.connect(lfoGain);
|
|
734
743
|
lfo.start();
|
|
735
744
|
return {
|
|
745
|
+
input,
|
|
746
|
+
output,
|
|
747
|
+
sendGain,
|
|
736
748
|
lfo,
|
|
737
749
|
lfoGain,
|
|
738
750
|
delayNodes,
|
|
739
|
-
|
|
740
|
-
output,
|
|
751
|
+
feedbackGains,
|
|
741
752
|
};
|
|
742
753
|
}
|
|
743
754
|
connectEffects(channel, gainNode) {
|
|
744
755
|
gainNode.connect(channel.merger);
|
|
745
756
|
channel.merger.connect(this.masterGain);
|
|
746
|
-
if (channel.reverbSendLevel
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
channel.merger.connect(delayNode);
|
|
750
|
-
});
|
|
751
|
-
channel.chorusEffect.output.connect(this.masterGain);
|
|
752
|
-
}
|
|
757
|
+
if (0 < channel.reverbSendLevel) {
|
|
758
|
+
channel.merger.connect(channel.reverbEffect.input);
|
|
759
|
+
channel.reverbEffect.output.connect(this.masterGain);
|
|
753
760
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
channel.chorusEffect.delayNodes.forEach((delayNode) => {
|
|
761
|
-
channel.merger.connect(delayNode);
|
|
762
|
-
});
|
|
763
|
-
channel.merger.connect(channel.reverbEffect.input);
|
|
764
|
-
channel.reverbEffect.output.connect(this.masterGain);
|
|
765
|
-
}
|
|
761
|
+
if (0 < channel.chorusSendLevel) {
|
|
762
|
+
channel.merger.connect(channel.chorusEffect.input);
|
|
763
|
+
channel.reverbEffect.output.connect(this.masterGain);
|
|
764
|
+
}
|
|
765
|
+
if (0 < this.chorus.sendToReverb) {
|
|
766
|
+
channel.chorusEffect.sendGain.connect(channel.reverbEffect.input);
|
|
766
767
|
}
|
|
767
768
|
}
|
|
768
769
|
cbToRatio(cb) {
|
|
@@ -1221,9 +1222,12 @@ export class Midy {
|
|
|
1221
1222
|
reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
|
|
1222
1223
|
}
|
|
1223
1224
|
setChorusSendLevel(channelNumber, chorusSendLevel) {
|
|
1225
|
+
const now = this.audioContext.currentTime;
|
|
1224
1226
|
const channel = this.channels[channelNumber];
|
|
1227
|
+
const chorusEffect = channel.chorusEffect;
|
|
1225
1228
|
channel.chorusSendLevel = chorusSendLevel / 127;
|
|
1226
|
-
|
|
1229
|
+
chorusEffect.output.gain.cancelScheduledValues(now);
|
|
1230
|
+
chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
|
|
1227
1231
|
}
|
|
1228
1232
|
setSostenutoPedal(channelNumber, value) {
|
|
1229
1233
|
const isOn = value >= 64;
|
|
@@ -1483,7 +1487,7 @@ export class Midy {
|
|
|
1483
1487
|
case 4: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca25.pdf
|
|
1484
1488
|
return this.handleMasterCoarseTuningSysEx(data);
|
|
1485
1489
|
case 5:
|
|
1486
|
-
return this.
|
|
1490
|
+
return this.handleGlobalParameterControlSysEx(data);
|
|
1487
1491
|
default:
|
|
1488
1492
|
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1489
1493
|
}
|
|
@@ -1560,13 +1564,13 @@ export class Midy {
|
|
|
1560
1564
|
this.masterCoarseTuning = coarseTuning - 64;
|
|
1561
1565
|
}
|
|
1562
1566
|
}
|
|
1563
|
-
|
|
1564
|
-
if (data[
|
|
1565
|
-
switch (data[
|
|
1567
|
+
handleGlobalParameterControlSysEx(data) {
|
|
1568
|
+
if (data[7] === 1) {
|
|
1569
|
+
switch (data[8]) {
|
|
1566
1570
|
case 1:
|
|
1567
|
-
return this.
|
|
1571
|
+
return this.handleReverbParameterSysEx(data);
|
|
1568
1572
|
case 2:
|
|
1569
|
-
return this.
|
|
1573
|
+
return this.handleChorusParameterSysEx(data);
|
|
1570
1574
|
default:
|
|
1571
1575
|
console.warn(`Unsupported Global Parameter Control Message: ${data}`);
|
|
1572
1576
|
}
|
|
@@ -1575,12 +1579,12 @@ export class Midy {
|
|
|
1575
1579
|
console.warn(`Unsupported Global Parameter Control Message: ${data}`);
|
|
1576
1580
|
}
|
|
1577
1581
|
}
|
|
1578
|
-
|
|
1579
|
-
switch (data[
|
|
1582
|
+
handleReverbParameterSysEx(data) {
|
|
1583
|
+
switch (data[9]) {
|
|
1580
1584
|
case 0:
|
|
1581
|
-
return this.setReverbType(data[
|
|
1585
|
+
return this.setReverbType(data[10]);
|
|
1582
1586
|
case 1:
|
|
1583
|
-
return this.setReverbTime(data[
|
|
1587
|
+
return this.setReverbTime(data[10]);
|
|
1584
1588
|
}
|
|
1585
1589
|
}
|
|
1586
1590
|
setReverbType(type) {
|
|
@@ -1640,41 +1644,109 @@ export class Midy {
|
|
|
1640
1644
|
// RT60 = -3 * delay / Math.log10(feedback)
|
|
1641
1645
|
// feedback = Math.pow(10, -3 * delay / RT60)
|
|
1642
1646
|
// delay estimation using ideal feedback
|
|
1643
|
-
//
|
|
1644
|
-
//
|
|
1645
|
-
// It
|
|
1647
|
+
// The structure of a concert hall is complex,
|
|
1648
|
+
// so estimates based on mean free path are unstable.
|
|
1649
|
+
// It is easier to determine the delay based on ideal feedback.
|
|
1650
|
+
// The average sound absorption coefficient
|
|
1651
|
+
// suitable for playing musical instruments is 0.18 to 0.28.
|
|
1646
1652
|
// delay = -RT60 * Math.log10(feedback) / 3
|
|
1647
1653
|
calcDelay(rt60, feedback) {
|
|
1648
1654
|
return -rt60 * Math.log10(feedback) / 3;
|
|
1649
1655
|
}
|
|
1650
|
-
|
|
1651
|
-
switch (data[
|
|
1656
|
+
handleChorusParameterSysEx(data) {
|
|
1657
|
+
switch (data[9]) {
|
|
1652
1658
|
case 0:
|
|
1653
|
-
return this.setChorusType(data[
|
|
1659
|
+
return this.setChorusType(data[10]);
|
|
1654
1660
|
case 1:
|
|
1655
|
-
return this.setChorusModRate(data[
|
|
1661
|
+
return this.setChorusModRate(data[10]);
|
|
1656
1662
|
case 2:
|
|
1657
|
-
return this.setChorusModDepth(data[
|
|
1663
|
+
return this.setChorusModDepth(data[10]);
|
|
1658
1664
|
case 3:
|
|
1659
|
-
return this.setChorusFeedback(data[
|
|
1665
|
+
return this.setChorusFeedback(data[10]);
|
|
1660
1666
|
case 4:
|
|
1661
|
-
return this.setChorusSendToReverb(data[
|
|
1667
|
+
return this.setChorusSendToReverb(data[10]);
|
|
1662
1668
|
}
|
|
1663
1669
|
}
|
|
1664
1670
|
setChorusType(type) {
|
|
1665
|
-
|
|
1671
|
+
switch (type) {
|
|
1672
|
+
case 0:
|
|
1673
|
+
return this.setChorusParameter(3, 5, 0, 0);
|
|
1674
|
+
case 1:
|
|
1675
|
+
return this.setChorusParameter(9, 19, 5, 0);
|
|
1676
|
+
case 2:
|
|
1677
|
+
return this.setChorusParameter(3, 19, 8, 0);
|
|
1678
|
+
case 3:
|
|
1679
|
+
return this.setChorusParameter(9, 16, 16, 0);
|
|
1680
|
+
case 4:
|
|
1681
|
+
return this.setChorusParameter(2, 24, 64, 0);
|
|
1682
|
+
case 5:
|
|
1683
|
+
return this.setChorusParameter(1, 5, 112, 0);
|
|
1684
|
+
default:
|
|
1685
|
+
console.warn(`Unsupported Chorus Type: ${type}`);
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
setChorusParameter(modRate, modDepth, feedback, sendToReverb) {
|
|
1689
|
+
this.setChorusModRate(modRate);
|
|
1690
|
+
this.setChorusModDepth(modDepth);
|
|
1691
|
+
this.setChorusFeedback(feedback);
|
|
1692
|
+
this.setChorusSendToReverb(sendToReverb);
|
|
1666
1693
|
}
|
|
1667
1694
|
setChorusModRate(value) {
|
|
1668
|
-
|
|
1695
|
+
const now = this.audioContext.currentTime;
|
|
1696
|
+
const modRate = this.getChorusModRate(value);
|
|
1697
|
+
this.chorus.modRate = modRate;
|
|
1698
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1699
|
+
const lfo = this.channels[i].chorusEffect.lfo;
|
|
1700
|
+
lfo.frequency.setValueAtTime(modRate, now);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
getChorusModRate(value) {
|
|
1704
|
+
return value * 0.122; // Hz
|
|
1669
1705
|
}
|
|
1670
1706
|
setChorusModDepth(value) {
|
|
1671
|
-
|
|
1707
|
+
const now = this.audioContext.currentTime;
|
|
1708
|
+
const modDepth = this.getChorusModDepth(value);
|
|
1709
|
+
this.chorus.modDepth = modDepth;
|
|
1710
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1711
|
+
const chorusEffect = this.channels[i].chorusEffect;
|
|
1712
|
+
chorusEffect.lfoGain.gain
|
|
1713
|
+
.cancelScheduledValues(now)
|
|
1714
|
+
.setValueAtTime(modDepth / 2, now);
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
getChorusModDepth(value) {
|
|
1718
|
+
return (value + 1) / 3200; // second
|
|
1672
1719
|
}
|
|
1673
1720
|
setChorusFeedback(value) {
|
|
1674
|
-
|
|
1721
|
+
const now = this.audioContext.currentTime;
|
|
1722
|
+
const feedback = this.getChorusFeedback(value);
|
|
1723
|
+
this.chorus.feedback = feedback;
|
|
1724
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1725
|
+
const chorusEffect = this.channels[i].chorusEffect;
|
|
1726
|
+
for (let j = 0; j < chorusEffect.feedbackGains.length; j++) {
|
|
1727
|
+
const feedbackGain = chorusEffect.feedbackGains[j];
|
|
1728
|
+
feedbackGain.gain
|
|
1729
|
+
.cancelScheduledValues(now)
|
|
1730
|
+
.setValueAtTime(feedback, now);
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
getChorusFeedback(value) {
|
|
1735
|
+
return value * 0.00763;
|
|
1675
1736
|
}
|
|
1676
1737
|
setChorusSendToReverb(value) {
|
|
1677
|
-
|
|
1738
|
+
const now = this.audioContext.currentTime;
|
|
1739
|
+
const sendToReverb = this.getChorusSendToReverb(value);
|
|
1740
|
+
this.chorus.sendToReverb = sendToReverb;
|
|
1741
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
1742
|
+
const chorusEffect = this.channels[i].chorusEffect;
|
|
1743
|
+
chorusEffect.sendGain.gain
|
|
1744
|
+
.cancelScheduledValues(now)
|
|
1745
|
+
.setValueAtTime(sendToReverb, now);
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
getChorusSendToReverb(value) {
|
|
1749
|
+
return value * 0.00787;
|
|
1678
1750
|
}
|
|
1679
1751
|
handleExclusiveMessage(data) {
|
|
1680
1752
|
console.warn(`Unsupported Exclusive Message: ${data}`);
|
package/package.json
CHANGED
package/script/midy-GM2.d.ts
CHANGED
|
@@ -56,6 +56,7 @@ export class MidyGM2 {
|
|
|
56
56
|
modDepth: number;
|
|
57
57
|
feedback: number;
|
|
58
58
|
sendToReverb: number;
|
|
59
|
+
delayTimes: any[];
|
|
59
60
|
};
|
|
60
61
|
mono: boolean;
|
|
61
62
|
omni: boolean;
|
|
@@ -102,11 +103,13 @@ export class MidyGM2 {
|
|
|
102
103
|
output: any;
|
|
103
104
|
};
|
|
104
105
|
chorusEffect: {
|
|
106
|
+
input: any;
|
|
107
|
+
output: any;
|
|
108
|
+
sendGain: any;
|
|
105
109
|
lfo: any;
|
|
106
110
|
lfoGain: any;
|
|
107
111
|
delayNodes: any[];
|
|
108
|
-
|
|
109
|
-
output: any;
|
|
112
|
+
feedbackGains: any[];
|
|
110
113
|
};
|
|
111
114
|
};
|
|
112
115
|
createChannels(audioContext: any): any[];
|
|
@@ -145,12 +148,14 @@ export class MidyGM2 {
|
|
|
145
148
|
input: any;
|
|
146
149
|
output: any;
|
|
147
150
|
};
|
|
148
|
-
createChorusEffect(audioContext: any
|
|
151
|
+
createChorusEffect(audioContext: any): {
|
|
152
|
+
input: any;
|
|
153
|
+
output: any;
|
|
154
|
+
sendGain: any;
|
|
149
155
|
lfo: any;
|
|
150
156
|
lfoGain: any;
|
|
151
157
|
delayNodes: any[];
|
|
152
|
-
|
|
153
|
-
output: any;
|
|
158
|
+
feedbackGains: any[];
|
|
154
159
|
};
|
|
155
160
|
connectEffects(channel: any, gainNode: any): void;
|
|
156
161
|
cbToRatio(cb: any): number;
|
|
@@ -226,19 +231,24 @@ export class MidyGM2 {
|
|
|
226
231
|
setMasterFineTuning(fineTuning: any): void;
|
|
227
232
|
handleMasterCoarseTuningSysEx(data: any): void;
|
|
228
233
|
setMasterCoarseTuning(coarseTuning: any): void;
|
|
229
|
-
|
|
230
|
-
|
|
234
|
+
handleGlobalParameterControlSysEx(data: any): void;
|
|
235
|
+
handleReverbParameterSysEx(data: any): void;
|
|
231
236
|
setReverbType(type: any): void;
|
|
232
237
|
getReverbTimeFromType(type: any): number | undefined;
|
|
233
238
|
setReverbTime(value: any): void;
|
|
234
239
|
getReverbTime(value: any): number;
|
|
235
240
|
calcDelay(rt60: any, feedback: any): number;
|
|
236
|
-
|
|
241
|
+
handleChorusParameterSysEx(data: any): void;
|
|
237
242
|
setChorusType(type: any): void;
|
|
243
|
+
setChorusParameter(modRate: any, modDepth: any, feedback: any, sendToReverb: any): void;
|
|
238
244
|
setChorusModRate(value: any): void;
|
|
245
|
+
getChorusModRate(value: any): number;
|
|
239
246
|
setChorusModDepth(value: any): void;
|
|
247
|
+
getChorusModDepth(value: any): number;
|
|
240
248
|
setChorusFeedback(value: any): void;
|
|
249
|
+
getChorusFeedback(value: any): number;
|
|
241
250
|
setChorusSendToReverb(value: any): void;
|
|
251
|
+
getChorusSendToReverb(value: any): number;
|
|
242
252
|
handleExclusiveMessage(data: any): void;
|
|
243
253
|
handleSysEx(data: any): void;
|
|
244
254
|
scheduleTask(callback: any, startTime: any): Promise<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":"AAuBA;
|
|
1
|
+
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}
|