32 lines
1.3 KiB
Plaintext
32 lines
1.3 KiB
Plaintext
function build() {
|
|
if (st.ctx) return true;
|
|
if (!Lazy.loaded('feature:eq-core') || !Lazy.loaded('feature:vocal-reducer')) {
|
|
loadSoundFeatures().then(()=>{apply(); Level.apply();}).catch(error=>toast(error.message));
|
|
return false;
|
|
}
|
|
try {
|
|
st.ctx = new AC();
|
|
st.filters = EQ_BANDS.map((b) => {
|
|
const f = st.ctx.createBiquadFilter();
|
|
f.type = b.type;
|
|
f.frequency.value = b.f;
|
|
f.Q.value = 1.0;
|
|
return f;
|
|
});
|
|
for (let i = 0; i < st.filters.length - 1; i++) st.filters[i].connect(st.filters[i + 1]);
|
|
// Loudness levelling: gain toward -14 LUFS, then a limiter so a boosted
|
|
// quiet track can never clip.
|
|
st.level = st.ctx.createGain();
|
|
st.limiter = st.ctx.createDynamicsCompressor();
|
|
st.limiter.threshold.value = -1; st.limiter.knee.value = 0; st.limiter.ratio.value = 20;
|
|
st.limiter.attack.value = 0.003; st.limiter.release.value = 0.25;
|
|
st.vocal = VocalReducer.create(st.ctx, st.filters[st.filters.length - 1]);
|
|
st.widener = EqCore.createWidener(st.ctx, st.vocal.output);
|
|
st.widener.output.connect(st.level);
|
|
st.level.connect(st.limiter);
|
|
st.limiter.connect(st.ctx.destination);
|
|
return true;
|
|
} catch { st.ctx = null; return false; }
|
|
}
|
|
|