-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaudio_enhancer.js
More file actions
112 lines (98 loc) · 3.73 KB
/
audio_enhancer.js
File metadata and controls
112 lines (98 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
class AudioEnhancer {
constructor(videoElement) {
if (!window.AudioContext) {
this.isSupported = false;
return;
}
this.isSupported = true;
this.isEnabled = false;
this.videoElement = videoElement;
this.audioContext = new AudioContext();
this.sourceNode = this.audioContext.createMediaElementSource(this.videoElement);
this.preamp = this.audioContext.createGain();
this.compressor = this.audioContext.createDynamicsCompressor();
this.bandFrequencies = [60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000];
this.filters = this.bandFrequencies.map(freq => {
const filter = this.audioContext.createBiquadFilter();
filter.type = 'peaking';
filter.frequency.value = freq;
filter.Q.value = 1.41;
filter.gain.value = 0;
return filter;
});
this.connectNodes();
}
connectNodes() {
this.sourceNode.disconnect();
if (this.isEnabled) {
let lastNode = this.preamp;
this.sourceNode.connect(this.preamp);
this.filters.forEach(filter => {
lastNode.connect(filter);
lastNode = filter;
});
lastNode.connect(this.compressor);
this.compressor.connect(this.audioContext.destination);
} else {
this.sourceNode.connect(this.audioContext.destination);
}
}
toggle(state) {
this.isEnabled = state;
this.connectNodes();
}
setCompressor(settings) {
if (!this.isSupported || !settings) return;
this.compressor.threshold.value = settings.threshold || -24;
this.compressor.knee.value = settings.knee || 30;
this.compressor.ratio.value = settings.ratio || 12;
this.compressor.attack.value = settings.attack || 0.003;
this.compressor.release.value = settings.release || 0.25;
}
changeGain(bandIndex, gainValue) {
if (!this.isSupported || bandIndex < 0 || bandIndex >= this.filters.length) return;
this.filters[bandIndex].gain.value = gainValue;
}
changePreamp(gainValue) {
if (!this.isSupported) return;
const linearValue = Math.pow(10, gainValue / 20);
this.preamp.gain.value = linearValue;
}
applySettings(settings) {
if (!this.isSupported || !settings) return;
this.toggle(settings.enabled);
if (typeof settings.preamp === 'number') {
this.changePreamp(settings.preamp);
}
if (Array.isArray(settings.bands)) {
settings.bands.forEach((gain, index) => {
this.changeGain(index, gain);
});
}
if (settings.compressor) {
this.setCompressor(settings.compressor);
} else {
this.setCompressor({});
}
}
getSettings() {
if (!this.isSupported) return { enabled: false, preamp: 0, bands: new Array(10).fill(0), customPresets: [] };
const preampDB = 20 * Math.log10(this.preamp.gain.value);
const bandGains = this.filters.map(filter => filter.gain.value);
return { enabled: this.isEnabled, preamp: preampDB, bands: bandGains };
}
destroy() {
if (!this.isSupported) return;
try {
this.sourceNode.disconnect();
this.preamp.disconnect();
this.compressor.disconnect();
this.filters.forEach(filter => filter.disconnect());
if (this.audioContext.state !== 'closed') {
this.audioContext.close();
}
} catch (e) {
console.error("Error al destruir AudioEnhancer:", e);
}
}
}