fix: [sound-logo] 오디오 합성 시 클리핑 소음 방지

- DynamicsCompressor 마스터 노드 추가 (threshold:-6dB, ratio:12)
- 모든 오디오 출력(시퀀서/음성/BGM)을 컴프레서 경유로 변경
- 다중 소스 합산 시 진폭 초과로 인한 디지털 클리핑 방지
This commit is contained in:
김보곤
2026-03-08 14:47:27 +09:00
parent 17ee94ff72
commit 94147cce56

View File

@@ -1383,10 +1383,26 @@ function soundLogo() {
},
getAudioCtx() {
if (!this.audioCtx) this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
if (!this.audioCtx) {
this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// 마스터 컴프레서 (클리핑 방지)
const comp = this.audioCtx.createDynamicsCompressor();
comp.threshold.value = -6;
comp.knee.value = 10;
comp.ratio.value = 12;
comp.attack.value = 0.003;
comp.release.value = 0.15;
comp.connect(this.audioCtx.destination);
this._masterNode = comp;
}
return this.audioCtx;
},
getMasterNode() {
const ctx = this.getAudioCtx();
return this._masterNode || ctx.destination;
},
// ===== Note helpers =====
getNoteLabel(n) {
if (n.type === 'rest') return '쉼표';
@@ -1461,7 +1477,7 @@ function soundLogo() {
gain.gain.setValueAtTime(vel * s, startTime + dur);
gain.gain.exponentialRampToValueAtTime(0.001, startTime + dur + r);
osc.connect(gain).connect(ctx.destination);
osc.connect(gain).connect(this.getMasterNode());
osc.start(startTime);
osc.stop(startTime + dur + r + 0.05);
});
@@ -1501,7 +1517,7 @@ function soundLogo() {
voiceSrc.buffer = this.voiceBuffer;
const voiceGain = ctx.createGain();
voiceGain.gain.value = this.voiceVolume;
voiceSrc.connect(voiceGain).connect(ctx.destination);
voiceSrc.connect(voiceGain).connect(this.getMasterNode());
voiceSrc.start(startTime + this.voiceDelay);
}
@@ -1511,7 +1527,7 @@ function soundLogo() {
bgmSrc.buffer = this.bgmBuffer;
const bgmGain = ctx.createGain();
bgmGain.gain.value = this.bgmVolume;
bgmSrc.connect(bgmGain).connect(ctx.destination);
bgmSrc.connect(bgmGain).connect(this.getMasterNode());
bgmSrc.start(startTime);
}
@@ -1532,6 +1548,7 @@ function soundLogo() {
if (this.audioCtx) {
this.audioCtx.close();
this.audioCtx = null;
this._masterNode = null;
}
this.isPlaying = false;
this.playingIdx = -1;
@@ -1765,7 +1782,7 @@ function soundLogo() {
src.buffer = this.voiceBuffer;
const gain = ctx.createGain();
gain.gain.value = this.voiceVolume;
src.connect(gain).connect(ctx.destination);
src.connect(gain).connect(this.getMasterNode());
src.start();
},
@@ -2010,7 +2027,7 @@ function soundLogo() {
src.buffer = this.bgmBuffer;
const gain = ctx.createGain();
gain.gain.value = this.bgmVolume;
src.connect(gain).connect(ctx.destination);
src.connect(gain).connect(this.getMasterNode());
src.start();
},