diff --git a/resources/views/rd/sound-logo/index.blade.php b/resources/views/rd/sound-logo/index.blade.php index 77de33bb..6eac4f14 100644 --- a/resources/views/rd/sound-logo/index.blade.php +++ b/resources/views/rd/sound-logo/index.blade.php @@ -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(); },