@marmooo/midy 0.0.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/midy-GM1.d.ts +0 -2
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +5 -9
- package/esm/midy-GM2.d.ts +31 -19
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +193 -56
- package/esm/midy-GMLite.js +5 -5
- package/esm/midy.d.ts +31 -19
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +193 -56
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +0 -2
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +5 -9
- package/script/midy-GM2.d.ts +31 -19
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +193 -56
- package/script/midy-GMLite.js +5 -5
- package/script/midy.d.ts +31 -19
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +193 -56
package/esm/midy.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ export class Midy {
|
|
|
4
4
|
volume: number;
|
|
5
5
|
pan: number;
|
|
6
6
|
portamentoTime: number;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
reverbSendLevel: number;
|
|
8
|
+
chorusSendLevel: number;
|
|
9
9
|
vibratoRate: number;
|
|
10
10
|
vibratoDepth: number;
|
|
11
11
|
vibratoDelay: number;
|
|
@@ -44,15 +44,22 @@ export class Midy {
|
|
|
44
44
|
reverbAlgorithm: (audioContext: any) => {
|
|
45
45
|
input: any;
|
|
46
46
|
output: any;
|
|
47
|
-
dryGain: any;
|
|
48
|
-
wetGain: any;
|
|
49
47
|
};
|
|
50
48
|
});
|
|
51
49
|
ticksPerBeat: number;
|
|
52
50
|
totalTime: number;
|
|
53
|
-
reverbFactor: number;
|
|
54
51
|
masterFineTuning: number;
|
|
55
52
|
masterCoarseTuning: number;
|
|
53
|
+
reverb: {
|
|
54
|
+
time: number;
|
|
55
|
+
feedback: number;
|
|
56
|
+
};
|
|
57
|
+
chorus: {
|
|
58
|
+
modRate: number;
|
|
59
|
+
modDepth: number;
|
|
60
|
+
feedback: number;
|
|
61
|
+
sendToReverb: number;
|
|
62
|
+
};
|
|
56
63
|
mono: boolean;
|
|
57
64
|
omni: boolean;
|
|
58
65
|
noteCheckInterval: number;
|
|
@@ -74,8 +81,6 @@ export class Midy {
|
|
|
74
81
|
reverbAlgorithm: (audioContext: any) => {
|
|
75
82
|
input: any;
|
|
76
83
|
output: any;
|
|
77
|
-
dryGain: any;
|
|
78
|
-
wetGain: any;
|
|
79
84
|
};
|
|
80
85
|
};
|
|
81
86
|
audioContext: any;
|
|
@@ -83,8 +88,6 @@ export class Midy {
|
|
|
83
88
|
reverbAlgorithm: (audioContext: any) => {
|
|
84
89
|
input: any;
|
|
85
90
|
output: any;
|
|
86
|
-
dryGain: any;
|
|
87
|
-
wetGain: any;
|
|
88
91
|
};
|
|
89
92
|
};
|
|
90
93
|
masterGain: any;
|
|
@@ -100,8 +103,6 @@ export class Midy {
|
|
|
100
103
|
reverbEffect: {
|
|
101
104
|
input: any;
|
|
102
105
|
output: any;
|
|
103
|
-
dryGain: any;
|
|
104
|
-
wetGain: any;
|
|
105
106
|
};
|
|
106
107
|
chorusEffect: {
|
|
107
108
|
lfo: any;
|
|
@@ -134,20 +135,18 @@ export class Midy {
|
|
|
134
135
|
currentTime(): number;
|
|
135
136
|
getActiveNotes(channel: any, time: any): Map<any, any>;
|
|
136
137
|
getActiveNote(noteList: any, time: any): any;
|
|
137
|
-
|
|
138
|
+
createConvolutionReverbImpulse(audioContext: any, decay: any, preDecay: any): any;
|
|
139
|
+
createConvolutionReverb(audioContext: any, impulse: any): {
|
|
138
140
|
input: any;
|
|
139
141
|
output: any;
|
|
140
|
-
dryGain: any;
|
|
141
|
-
wetGain: any;
|
|
142
142
|
convolverNode: any;
|
|
143
143
|
};
|
|
144
144
|
createCombFilter(audioContext: any, input: any, delay: any, feedback: any): any;
|
|
145
145
|
createAllpassFilter(audioContext: any, input: any, delay: any, feedback: any): any;
|
|
146
|
-
|
|
146
|
+
generateDistributedArray(center: any, count: any, varianceRatio?: number, randomness?: number): any[];
|
|
147
|
+
createSchroederReverb(audioContext: any, combDelays: any, combFeedbacks: any, allpassDelays: any, allpassFeedbacks: any): {
|
|
147
148
|
input: any;
|
|
148
149
|
output: any;
|
|
149
|
-
dryGain: any;
|
|
150
|
-
wetGain: any;
|
|
151
150
|
};
|
|
152
151
|
createChorusEffect(audioContext: any, options?: {}): {
|
|
153
152
|
lfo: any;
|
|
@@ -196,8 +195,8 @@ export class Midy {
|
|
|
196
195
|
updateChannelGain(channel: any): void;
|
|
197
196
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
198
197
|
setPortamento(channelNumber: any, value: any): void;
|
|
199
|
-
setReverbSendLevel(channelNumber: any,
|
|
200
|
-
setChorusSendLevel(channelNumber: any,
|
|
198
|
+
setReverbSendLevel(channelNumber: any, reverbSendLevel: any): void;
|
|
199
|
+
setChorusSendLevel(channelNumber: any, chorusSendLevel: any): void;
|
|
201
200
|
setSostenutoPedal(channelNumber: any, value: any): void;
|
|
202
201
|
setSoftPedal(channelNumber: any, softPedal: any): void;
|
|
203
202
|
setVibratoRate(channelNumber: any, vibratoRate: any): void;
|
|
@@ -237,6 +236,19 @@ export class Midy {
|
|
|
237
236
|
setMasterFineTuning(fineTuning: any): void;
|
|
238
237
|
handleMasterCoarseTuningSysEx(data: any): void;
|
|
239
238
|
setMasterCoarseTuning(coarseTuning: any): void;
|
|
239
|
+
handleGlobalParameterControl(data: any): void;
|
|
240
|
+
handleReverbParameter(data: any): void;
|
|
241
|
+
setReverbType(type: any): void;
|
|
242
|
+
getReverbTimeFromType(type: any): number | undefined;
|
|
243
|
+
setReverbTime(value: any): void;
|
|
244
|
+
getReverbTime(value: any): number;
|
|
245
|
+
calcDelay(rt60: any, feedback: any): number;
|
|
246
|
+
handleChorusParameter(data: any): void;
|
|
247
|
+
setChorusType(type: any): void;
|
|
248
|
+
setChorusModRate(value: any): void;
|
|
249
|
+
setChorusModDepth(value: any): void;
|
|
250
|
+
setChorusFeedback(value: any): void;
|
|
251
|
+
setChorusSendToReverb(value: any): void;
|
|
240
252
|
handleExclusiveMessage(data: any): void;
|
|
241
253
|
handleSysEx(data: any): void;
|
|
242
254
|
scheduleTask(callback: any, startTime: any): Promise<any>;
|
package/esm/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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"}
|
package/esm/midy.js
CHANGED
|
@@ -64,12 +64,6 @@ export class Midy {
|
|
|
64
64
|
writable: true,
|
|
65
65
|
value: 0
|
|
66
66
|
});
|
|
67
|
-
Object.defineProperty(this, "reverbFactor", {
|
|
68
|
-
enumerable: true,
|
|
69
|
-
configurable: true,
|
|
70
|
-
writable: true,
|
|
71
|
-
value: 0.1
|
|
72
|
-
});
|
|
73
67
|
Object.defineProperty(this, "masterFineTuning", {
|
|
74
68
|
enumerable: true,
|
|
75
69
|
configurable: true,
|
|
@@ -82,6 +76,26 @@ export class Midy {
|
|
|
82
76
|
writable: true,
|
|
83
77
|
value: 0
|
|
84
78
|
}); // cb
|
|
79
|
+
Object.defineProperty(this, "reverb", {
|
|
80
|
+
enumerable: true,
|
|
81
|
+
configurable: true,
|
|
82
|
+
writable: true,
|
|
83
|
+
value: {
|
|
84
|
+
time: this.getReverbTime(64),
|
|
85
|
+
feedback: 0.2,
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
Object.defineProperty(this, "chorus", {
|
|
89
|
+
enumerable: true,
|
|
90
|
+
configurable: true,
|
|
91
|
+
writable: true,
|
|
92
|
+
value: {
|
|
93
|
+
modRate: 3 * 0.122,
|
|
94
|
+
modDepth: (3 + 1) / 3.2,
|
|
95
|
+
feedback: 8 * 0.763,
|
|
96
|
+
sendToReverb: 0 * 0.787,
|
|
97
|
+
}
|
|
98
|
+
});
|
|
85
99
|
Object.defineProperty(this, "mono", {
|
|
86
100
|
enumerable: true,
|
|
87
101
|
configurable: true,
|
|
@@ -190,8 +204,19 @@ export class Midy {
|
|
|
190
204
|
writable: true,
|
|
191
205
|
value: {
|
|
192
206
|
reverbAlgorithm: (audioContext) => {
|
|
193
|
-
|
|
194
|
-
|
|
207
|
+
const { time: rt60, feedback } = this.reverb;
|
|
208
|
+
// const delay = this.calcDelay(rt60, feedback);
|
|
209
|
+
// const impulse = this.createConvolutionReverbImpulse(
|
|
210
|
+
// audioContext,
|
|
211
|
+
// rt60,
|
|
212
|
+
// delay,
|
|
213
|
+
// );
|
|
214
|
+
// return this.createConvolutionReverb(audioContext, impulse);
|
|
215
|
+
const combFeedbacks = this.generateDistributedArray(feedback, 4);
|
|
216
|
+
const combDelays = combFeedbacks.map((feedback) => this.calcDelay(rt60, feedback));
|
|
217
|
+
const allpassFeedbacks = this.generateDistributedArray(feedback, 4);
|
|
218
|
+
const allpassDelays = allpassFeedbacks.map((feedback) => this.calcDelay(rt60, feedback));
|
|
219
|
+
return this.createSchroederReverb(audioContext, combFeedbacks, combDelays, allpassFeedbacks, allpassDelays);
|
|
195
220
|
},
|
|
196
221
|
}
|
|
197
222
|
});
|
|
@@ -596,12 +621,7 @@ export class Midy {
|
|
|
596
621
|
}
|
|
597
622
|
return noteList[0];
|
|
598
623
|
}
|
|
599
|
-
|
|
600
|
-
const { decay = 0.8, preDecay = 0, } = options;
|
|
601
|
-
const input = new GainNode(audioContext);
|
|
602
|
-
const output = new GainNode(audioContext);
|
|
603
|
-
const dryGain = new GainNode(audioContext);
|
|
604
|
-
const wetGain = new GainNode(audioContext);
|
|
624
|
+
createConvolutionReverbImpulse(audioContext, decay, preDecay) {
|
|
605
625
|
const sampleRate = audioContext.sampleRate;
|
|
606
626
|
const length = sampleRate * decay;
|
|
607
627
|
const impulse = new AudioBuffer({
|
|
@@ -621,18 +641,17 @@ export class Midy {
|
|
|
621
641
|
channelData[i] = (Math.random() * 2 - 1) * attenuation;
|
|
622
642
|
}
|
|
623
643
|
}
|
|
644
|
+
return impulse;
|
|
645
|
+
}
|
|
646
|
+
createConvolutionReverb(audioContext, impulse) {
|
|
647
|
+
const output = new GainNode(audioContext);
|
|
624
648
|
const convolverNode = new ConvolverNode(audioContext, {
|
|
625
649
|
buffer: impulse,
|
|
626
650
|
});
|
|
627
|
-
|
|
628
|
-
convolverNode.connect(wetGain);
|
|
629
|
-
wetGain.connect(output);
|
|
630
|
-
dryGain.connect(output);
|
|
651
|
+
convolverNode.connect(output);
|
|
631
652
|
return {
|
|
632
|
-
input,
|
|
653
|
+
input: convolverNode,
|
|
633
654
|
output,
|
|
634
|
-
dryGain,
|
|
635
|
-
wetGain,
|
|
636
655
|
convolverNode,
|
|
637
656
|
};
|
|
638
657
|
}
|
|
@@ -660,17 +679,24 @@ export class Midy {
|
|
|
660
679
|
delayNode.connect(passGain);
|
|
661
680
|
return passGain;
|
|
662
681
|
}
|
|
682
|
+
generateDistributedArray(center, count, varianceRatio = 0.1, randomness = 0.05) {
|
|
683
|
+
const variance = center * varianceRatio;
|
|
684
|
+
const array = new Array(count);
|
|
685
|
+
for (let i = 0; i < count; i++) {
|
|
686
|
+
const fraction = i / (count - 1 || 1);
|
|
687
|
+
const value = center - variance + fraction * 2 * variance;
|
|
688
|
+
array[i] = value * (1 - (Math.random() * 2 - 1) * randomness);
|
|
689
|
+
}
|
|
690
|
+
return array;
|
|
691
|
+
}
|
|
663
692
|
// https://hajim.rochester.edu/ece/sites/zduan/teaching/ece472/reading/Schroeder_1962.pdf
|
|
664
693
|
// M.R.Schroeder, "Natural Sounding Artificial Reverberation", J.Audio Eng. Soc., vol.10, p.219, 1962
|
|
665
|
-
createSchroederReverb(audioContext,
|
|
666
|
-
const { combDelays = [0.31, 0.34, 0.37, 0.40], combFeedbacks = [0.86, 0.87, 0.88, 0.89], allpassDelays = [0.02, 0.05], allpassFeedbacks = [0.7, 0.7], mix = 0.5, } = options;
|
|
694
|
+
createSchroederReverb(audioContext, combDelays, combFeedbacks, allpassDelays, allpassFeedbacks) {
|
|
667
695
|
const input = new GainNode(audioContext);
|
|
668
696
|
const output = new GainNode(audioContext);
|
|
669
697
|
const mergerGain = new GainNode(audioContext, {
|
|
670
698
|
gain: 1 / (combDelays.length * 2),
|
|
671
699
|
});
|
|
672
|
-
const dryGain = new GainNode(audioContext, { gain: 1 - mix });
|
|
673
|
-
const wetGain = new GainNode(audioContext, { gain: mix });
|
|
674
700
|
for (let i = 0; i < combDelays.length; i++) {
|
|
675
701
|
const comb = this.createCombFilter(audioContext, input, combDelays[i], combFeedbacks[i]);
|
|
676
702
|
comb.connect(mergerGain);
|
|
@@ -680,11 +706,8 @@ export class Midy {
|
|
|
680
706
|
const allpass = this.createAllpassFilter(audioContext, (i === 0) ? mergerGain : allpasses.at(-1), allpassDelays[i], allpassFeedbacks[i]);
|
|
681
707
|
allpasses.push(allpass);
|
|
682
708
|
}
|
|
683
|
-
allpasses.at(-1).connect(
|
|
684
|
-
input
|
|
685
|
-
dryGain.connect(output);
|
|
686
|
-
wetGain.connect(output);
|
|
687
|
-
return { input, output, dryGain, wetGain };
|
|
709
|
+
allpasses.at(-1).connect(output);
|
|
710
|
+
return { input, output };
|
|
688
711
|
}
|
|
689
712
|
createChorusEffect(audioContext, options = {}) {
|
|
690
713
|
const { chorusCount = 2, chorusRate = 0.6, chorusDepth = 0.15, delay = 0.01, variance = delay * 0.1, } = options;
|
|
@@ -719,11 +742,9 @@ export class Midy {
|
|
|
719
742
|
}
|
|
720
743
|
connectEffects(channel, gainNode) {
|
|
721
744
|
gainNode.connect(channel.merger);
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}
|
|
726
|
-
else { // chorus
|
|
745
|
+
channel.merger.connect(this.masterGain);
|
|
746
|
+
if (channel.reverbSendLevel === 0) {
|
|
747
|
+
if (channel.chorusSendLevel !== 0) { // chorus
|
|
727
748
|
channel.chorusEffect.delayNodes.forEach((delayNode) => {
|
|
728
749
|
channel.merger.connect(delayNode);
|
|
729
750
|
});
|
|
@@ -731,7 +752,7 @@ export class Midy {
|
|
|
731
752
|
}
|
|
732
753
|
}
|
|
733
754
|
else {
|
|
734
|
-
if (channel.
|
|
755
|
+
if (channel.chorusSendLevel === 0) { // reverb
|
|
735
756
|
channel.merger.connect(channel.reverbEffect.input);
|
|
736
757
|
channel.reverbEffect.output.connect(this.masterGain);
|
|
737
758
|
}
|
|
@@ -1187,23 +1208,22 @@ export class Midy {
|
|
|
1187
1208
|
this.releaseSustainPedal(channelNumber, value);
|
|
1188
1209
|
}
|
|
1189
1210
|
}
|
|
1211
|
+
// TODO
|
|
1190
1212
|
setPortamento(channelNumber, value) {
|
|
1191
1213
|
this.channels[channelNumber].portamento = value >= 64;
|
|
1192
1214
|
}
|
|
1193
|
-
setReverbSendLevel(channelNumber,
|
|
1215
|
+
setReverbSendLevel(channelNumber, reverbSendLevel) {
|
|
1194
1216
|
const now = this.audioContext.currentTime;
|
|
1195
1217
|
const channel = this.channels[channelNumber];
|
|
1196
1218
|
const reverbEffect = channel.reverbEffect;
|
|
1197
|
-
channel.
|
|
1198
|
-
reverbEffect.
|
|
1199
|
-
reverbEffect.
|
|
1200
|
-
reverbEffect.wetGain.gain.cancelScheduledValues(now);
|
|
1201
|
-
reverbEffect.wetGain.gain.setValueAtTime(channel.reverb, now);
|
|
1219
|
+
channel.reverbSendLevel = reverbSendLevel / 127;
|
|
1220
|
+
reverbEffect.output.gain.cancelScheduledValues(now);
|
|
1221
|
+
reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
|
|
1202
1222
|
}
|
|
1203
|
-
setChorusSendLevel(channelNumber,
|
|
1223
|
+
setChorusSendLevel(channelNumber, chorusSendLevel) {
|
|
1204
1224
|
const channel = this.channels[channelNumber];
|
|
1205
|
-
channel.
|
|
1206
|
-
channel.chorusEffect.lfoGain = channel.
|
|
1225
|
+
channel.chorusSendLevel = chorusSendLevel / 127;
|
|
1226
|
+
channel.chorusEffect.lfoGain = channel.chorusSendLevel;
|
|
1207
1227
|
}
|
|
1208
1228
|
setSostenutoPedal(channelNumber, value) {
|
|
1209
1229
|
const isOn = value >= 64;
|
|
@@ -1427,11 +1447,11 @@ export class Midy {
|
|
|
1427
1447
|
this.GM2SystemOn();
|
|
1428
1448
|
break;
|
|
1429
1449
|
default:
|
|
1430
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1450
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1431
1451
|
}
|
|
1432
1452
|
break;
|
|
1433
1453
|
default:
|
|
1434
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1454
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1435
1455
|
}
|
|
1436
1456
|
}
|
|
1437
1457
|
GM1SystemOn() {
|
|
@@ -1462,9 +1482,10 @@ export class Midy {
|
|
|
1462
1482
|
return this.handleMasterFineTuningSysEx(data);
|
|
1463
1483
|
case 4: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca25.pdf
|
|
1464
1484
|
return this.handleMasterCoarseTuningSysEx(data);
|
|
1465
|
-
|
|
1485
|
+
case 5:
|
|
1486
|
+
return this.handleGlobalParameterControl(data);
|
|
1466
1487
|
default:
|
|
1467
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1488
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1468
1489
|
}
|
|
1469
1490
|
break;
|
|
1470
1491
|
case 8:
|
|
@@ -1473,7 +1494,7 @@ export class Midy {
|
|
|
1473
1494
|
// // TODO
|
|
1474
1495
|
// return this.handleScaleOctaveTuning1ByteFormat();
|
|
1475
1496
|
default:
|
|
1476
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1497
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1477
1498
|
}
|
|
1478
1499
|
break;
|
|
1479
1500
|
case 9:
|
|
@@ -1485,7 +1506,7 @@ export class Midy {
|
|
|
1485
1506
|
// // TODO
|
|
1486
1507
|
// return this.setControlChange();
|
|
1487
1508
|
default:
|
|
1488
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1509
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1489
1510
|
}
|
|
1490
1511
|
break;
|
|
1491
1512
|
case 10:
|
|
@@ -1494,11 +1515,11 @@ export class Midy {
|
|
|
1494
1515
|
// // TODO
|
|
1495
1516
|
// return this.handleKeyBasedInstrumentControl();
|
|
1496
1517
|
default:
|
|
1497
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1518
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1498
1519
|
}
|
|
1499
1520
|
break;
|
|
1500
1521
|
default:
|
|
1501
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1522
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1502
1523
|
}
|
|
1503
1524
|
}
|
|
1504
1525
|
handleMasterVolumeSysEx(data) {
|
|
@@ -1539,8 +1560,124 @@ export class Midy {
|
|
|
1539
1560
|
this.masterCoarseTuning = coarseTuning - 64;
|
|
1540
1561
|
}
|
|
1541
1562
|
}
|
|
1563
|
+
handleGlobalParameterControl(data) {
|
|
1564
|
+
if (data[5] === 1) {
|
|
1565
|
+
switch (data[6]) {
|
|
1566
|
+
case 1:
|
|
1567
|
+
return this.handleReverbParameter(data);
|
|
1568
|
+
case 2:
|
|
1569
|
+
return this.handleChorusParameter(data);
|
|
1570
|
+
default:
|
|
1571
|
+
console.warn(`Unsupported Global Parameter Control Message: ${data}`);
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
else {
|
|
1575
|
+
console.warn(`Unsupported Global Parameter Control Message: ${data}`);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
handleReverbParameter(data) {
|
|
1579
|
+
switch (data[7]) {
|
|
1580
|
+
case 0:
|
|
1581
|
+
return this.setReverbType(data[8]);
|
|
1582
|
+
case 1:
|
|
1583
|
+
return this.setReverbTime(data[8]);
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
setReverbType(type) {
|
|
1587
|
+
this.reverb.time = this.getReverbTimeFromType(type);
|
|
1588
|
+
this.reverb.feedback = (type === 8) ? 0.1 : 0.2;
|
|
1589
|
+
const { audioContext, channels, options } = this;
|
|
1590
|
+
for (let i = 0; i < channels.length; i++) {
|
|
1591
|
+
channels[i].reverbEffect = options.reverbAlgorithm(audioContext);
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
getReverbTimeFromType(type) {
|
|
1595
|
+
switch (type) {
|
|
1596
|
+
case 0:
|
|
1597
|
+
return this.getReverbTime(44);
|
|
1598
|
+
case 1:
|
|
1599
|
+
return this.getReverbTime(50);
|
|
1600
|
+
case 2:
|
|
1601
|
+
return this.getReverbTime(56);
|
|
1602
|
+
case 3:
|
|
1603
|
+
return this.getReverbTime(64);
|
|
1604
|
+
case 4:
|
|
1605
|
+
return this.getReverbTime(64);
|
|
1606
|
+
case 8:
|
|
1607
|
+
return this.getReverbTime(50);
|
|
1608
|
+
default:
|
|
1609
|
+
console.warn(`Unsupported Reverb Time: ${type}`);
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
setReverbTime(value) {
|
|
1613
|
+
this.reverb.time = this.getReverbTime(value);
|
|
1614
|
+
const { audioContext, channels, options } = this;
|
|
1615
|
+
for (let i = 0; i < channels.length; i++) {
|
|
1616
|
+
channels[i].reverbEffect = options.reverbAlgorithm(audioContext);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
getReverbTime(value) {
|
|
1620
|
+
return Math.pow(Math.E, (value - 40) * 0.025);
|
|
1621
|
+
}
|
|
1622
|
+
// mean free path equation
|
|
1623
|
+
// https://repository.dl.itc.u-tokyo.ac.jp/record/8550/files/A31912.pdf
|
|
1624
|
+
// 江田和司, 拡散性制御に基づく室内音響設計に向けた音場解析に関する研究, 2015
|
|
1625
|
+
// V: room size (m^3)
|
|
1626
|
+
// S: room surface area (m^2)
|
|
1627
|
+
// meanFreePath = 4V / S (m)
|
|
1628
|
+
// delay estimation using mean free path
|
|
1629
|
+
// t: degree Celsius, generally used 20
|
|
1630
|
+
// c: speed of sound = 331.5 + 0.61t = 331.5 * 0.61 * 20 = 343.7 (m/s)
|
|
1631
|
+
// delay = meanFreePath / c (s)
|
|
1632
|
+
// feedback equation
|
|
1633
|
+
// RT60 means that the energy is reduced to Math.pow(10, -6).
|
|
1634
|
+
// Since energy is proportional to the square of the amplitude,
|
|
1635
|
+
// the amplitude is reduced to Math.pow(10, -3).
|
|
1636
|
+
// When this is done through n feedbacks,
|
|
1637
|
+
// Math.pow(feedback, n) = Math.pow(10, -3)
|
|
1638
|
+
// Math.pow(feedback, RT60 / delay) = Math.pow(10, -3)
|
|
1639
|
+
// RT60 / delay * Math.log10(feedback) = -3
|
|
1640
|
+
// RT60 = -3 * delay / Math.log10(feedback)
|
|
1641
|
+
// feedback = Math.pow(10, -3 * delay / RT60)
|
|
1642
|
+
// delay estimation using ideal feedback
|
|
1643
|
+
// A suitable average sound absorption coefficient is 0.18-0.28.
|
|
1644
|
+
// Since the structure of the hall is complex,
|
|
1645
|
+
// It would be easier to determine the delay based on the ideal feedback.
|
|
1646
|
+
// delay = -RT60 * Math.log10(feedback) / 3
|
|
1647
|
+
calcDelay(rt60, feedback) {
|
|
1648
|
+
return -rt60 * Math.log10(feedback) / 3;
|
|
1649
|
+
}
|
|
1650
|
+
handleChorusParameter(data) {
|
|
1651
|
+
switch (data[7]) {
|
|
1652
|
+
case 0:
|
|
1653
|
+
return this.setChorusType(data[8]);
|
|
1654
|
+
case 1:
|
|
1655
|
+
return this.setChorusModRate(data[8]);
|
|
1656
|
+
case 2:
|
|
1657
|
+
return this.setChorusModDepth(data[8]);
|
|
1658
|
+
case 3:
|
|
1659
|
+
return this.setChorusFeedback(data[8]);
|
|
1660
|
+
case 4:
|
|
1661
|
+
return this.setChorusSendToReverb(data[8]);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
setChorusType(type) {
|
|
1665
|
+
// TODO
|
|
1666
|
+
}
|
|
1667
|
+
setChorusModRate(value) {
|
|
1668
|
+
// TODO
|
|
1669
|
+
}
|
|
1670
|
+
setChorusModDepth(value) {
|
|
1671
|
+
// TODO
|
|
1672
|
+
}
|
|
1673
|
+
setChorusFeedback(value) {
|
|
1674
|
+
// TODO
|
|
1675
|
+
}
|
|
1676
|
+
setChorusSendToReverb(value) {
|
|
1677
|
+
// TODO
|
|
1678
|
+
}
|
|
1542
1679
|
handleExclusiveMessage(data) {
|
|
1543
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1680
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1544
1681
|
}
|
|
1545
1682
|
handleSysEx(data) {
|
|
1546
1683
|
switch (data[0]) {
|
|
@@ -1573,8 +1710,8 @@ Object.defineProperty(Midy, "channelSettings", {
|
|
|
1573
1710
|
volume: 100 / 127,
|
|
1574
1711
|
pan: 64,
|
|
1575
1712
|
portamentoTime: 0,
|
|
1576
|
-
|
|
1577
|
-
|
|
1713
|
+
reverbSendLevel: 0,
|
|
1714
|
+
chorusSendLevel: 0,
|
|
1578
1715
|
vibratoRate: 5,
|
|
1579
1716
|
vibratoDepth: 0.5,
|
|
1580
1717
|
vibratoDelay: 2.5,
|
package/package.json
CHANGED
package/script/midy-GM1.d.ts
CHANGED
package/script/midy-GM1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqBA;IAmBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA9CD,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IAyBhB,kBAAgC;IAChC,gBAA4C;IAE5C,gBAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED
|
|
1
|
+
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAqBA;IAmBE;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA9CD,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IAyBhB,kBAAgC;IAChC,gBAA4C;IAE5C,gBAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAcC;IAED,yCAUC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA8DC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,kDAGC;IAED,2BAEC;IAED,4BAEC;IAED,sCAGC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHA6BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIA8CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,mFA+BC;IAED,qCAcC;IAED,yDAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,kFAeC;IAED,2DAMC;IAED,oCAkBC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAUC;IAED,kDAKC;IAED,iEAOC;IAED,8CAKC;IAED,yDAMC;IAED,gDAKC;IAED,6DAMC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAnjCD;IAOE,gFAKC;IAXD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|
package/script/midy-GM1.js
CHANGED
|
@@ -192,14 +192,10 @@ class MidyGM1 {
|
|
|
192
192
|
const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
|
|
193
193
|
gainL.connect(merger, 0, 0);
|
|
194
194
|
gainR.connect(merger, 0, 1);
|
|
195
|
-
const reverbEffect = this.createConvolutionReverb(audioContext);
|
|
196
|
-
const chorusEffect = this.createChorusEffect(audioContext);
|
|
197
195
|
return {
|
|
198
196
|
gainL,
|
|
199
197
|
gainR,
|
|
200
198
|
merger,
|
|
201
|
-
reverbEffect,
|
|
202
|
-
chorusEffect,
|
|
203
199
|
};
|
|
204
200
|
}
|
|
205
201
|
createChannels(audioContext) {
|
|
@@ -959,11 +955,11 @@ class MidyGM1 {
|
|
|
959
955
|
case 2: // GM System Off
|
|
960
956
|
break;
|
|
961
957
|
default:
|
|
962
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
958
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
963
959
|
}
|
|
964
960
|
break;
|
|
965
961
|
default:
|
|
966
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
962
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
967
963
|
}
|
|
968
964
|
}
|
|
969
965
|
GM1SystemOn() {
|
|
@@ -982,11 +978,11 @@ class MidyGM1 {
|
|
|
982
978
|
case 1:
|
|
983
979
|
return this.handleMasterVolumeSysEx(data);
|
|
984
980
|
default:
|
|
985
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
981
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
986
982
|
}
|
|
987
983
|
break;
|
|
988
984
|
default:
|
|
989
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
985
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
990
986
|
}
|
|
991
987
|
}
|
|
992
988
|
handleMasterVolumeSysEx(data) {
|
|
@@ -1004,7 +1000,7 @@ class MidyGM1 {
|
|
|
1004
1000
|
}
|
|
1005
1001
|
}
|
|
1006
1002
|
handleExclusiveMessage(data) {
|
|
1007
|
-
console.warn(`Unsupported Exclusive Message ${data}`);
|
|
1003
|
+
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
1008
1004
|
}
|
|
1009
1005
|
handleSysEx(data) {
|
|
1010
1006
|
switch (data[0]) {
|