diff --git a/resources/views/rd/sound-logo/index.blade.php b/resources/views/rd/sound-logo/index.blade.php index b02e9a48..77de33bb 100644 --- a/resources/views/rd/sound-logo/index.blade.php +++ b/resources/views/rd/sound-logo/index.blade.php @@ -1836,25 +1836,23 @@ function soundLogo() { this.bgmProgress = '프롬프트 설정 중...'; ws.send(JSON.stringify({ - client_content: { + clientContent: { weightedPrompts: [{ text: this.bgmPrompt, weight: 1.0 }] } })); ws.send(JSON.stringify({ - music_generation_config: { - musicGenerationConfig: { - bpm: this.bgmBpm, - density: this.bgmDensity / 100, - brightness: this.bgmBrightness / 100, - scale: this.bgmScale, - temperature: 1.0, - } + musicGenerationConfig: { + bpm: this.bgmBpm, + density: this.bgmDensity / 100, + brightness: this.bgmBrightness / 100, + scale: this.bgmScale, + temperature: 1.0, } })); ws.send(JSON.stringify({ - playback_control: { playbackControl: 'PLAY' } + playbackControl: 'PLAY' })); playStartTime = Date.now(); this.bgmProgress = '음악 생성 중... 0/' + duration + '초'; @@ -1920,7 +1918,7 @@ function soundLogo() { setTimeout(() => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ - playback_control: { playbackControl: 'STOP' } + playbackControl: 'STOP' })); setTimeout(() => { if (ws.readyState === WebSocket.OPEN) ws.close(); @@ -1937,7 +1935,8 @@ function soundLogo() { async decodeBgmChunks(chunks) { try { - // base64 청크들을 합쳐서 하나의 PCM 데이터로 변환 + console.log('[Lyria] 오디오 디코딩 시작: ' + chunks.length + '개 청크'); + // base64 청크들을 합쳐서 하나의 바이트 배열로 변환 const allBytes = []; for (const chunk of chunks) { const binaryStr = atob(chunk); @@ -1946,8 +1945,28 @@ function soundLogo() { } } const pcmData = new Uint8Array(allBytes); + console.log('[Lyria] 전체 PCM 크기:', pcmData.length, 'bytes'); - // Lyria RealTime: 16-bit PCM, stereo, 48kHz (little-endian) + if (pcmData.length < 4) { + this.bgmError = '유효한 오디오 데이터가 없습니다.'; + this.bgmLoading = false; + return; + } + + const ctx = this.getAudioCtx(); + + // WAV 헤더 감지 (RIFF 매직넘버) → decodeAudioData 사용 + const hasWavHeader = pcmData[0] === 0x52 && pcmData[1] === 0x49 && pcmData[2] === 0x46 && pcmData[3] === 0x46; + if (hasWavHeader) { + console.log('[Lyria] WAV 헤더 감지, decodeAudioData 사용'); + const buffer = await ctx.decodeAudioData(pcmData.buffer.slice(0)); + this.bgmBuffer = buffer; + this.toast('배경음악 생성 완료 (' + buffer.duration.toFixed(1) + '초)'); + return; + } + + // Raw PCM: Lyria RealTime — 16-bit PCM, stereo, 48kHz (little-endian) + console.log('[Lyria] Raw PCM 디코딩: 48kHz, stereo, 16-bit LE'); const sampleRate = 48000; const numChannels = 2; const bytesPerSample = 2; @@ -1959,7 +1978,6 @@ function soundLogo() { return; } - const ctx = this.getAudioCtx(); const buffer = ctx.createBuffer(numChannels, numSamples, sampleRate); const view = new DataView(pcmData.buffer); @@ -1968,7 +1986,7 @@ function soundLogo() { for (let i = 0; i < numSamples; i++) { const byteOffset = (i * numChannels + ch) * bytesPerSample; if (byteOffset + 1 < pcmData.length) { - channelData[i] = view.getInt16(byteOffset, true) / 32768; // little-endian + channelData[i] = view.getInt16(byteOffset, true) / 32768; } } } @@ -1976,6 +1994,7 @@ function soundLogo() { this.bgmBuffer = buffer; this.toast('배경음악 생성 완료 (' + buffer.duration.toFixed(1) + '초)'); } catch (e) { + console.error('[Lyria] 오디오 디코딩 실패:', e); this.bgmError = '오디오 디코딩 실패: ' + e.message; this.toast('배경음악 오디오 처리에 실패했습니다.', 'error'); } finally {