- features/rd/sound-logo-studio.md (사운드 로고 스튜디오) - dev/changes/20260306_purchase_request_payment_method.md (품의서 지급방법)
245 lines
8.6 KiB
Markdown
245 lines
8.6 KiB
Markdown
# 사운드 로고 스튜디오
|
|
|
|
> **작성일**: 2026-03-08
|
|
> **상태**: 운영 중
|
|
> **라우트**: `/rd/sound-logo`
|
|
> **뷰**: `resources/views/rd/sound-logo/index.blade.php`
|
|
|
|
---
|
|
|
|
## 1. 개요
|
|
|
|
사운드 로고 스튜디오는 기업 시그니처 사운드(사운드 로고)를 제작하는 올인원 도구이다. Web Audio API 기반 시퀀서, Gemini AI 어시스트, TTS 음성 오버레이, Lyria RealTime BGM 생성을 하나의 SPA에서 통합 제공한다.
|
|
|
|
**핵심 기능:**
|
|
- 시퀀서 기반 사운드 로고 수동/프리셋 제작
|
|
- Gemini AI가 프롬프트 기반으로 음표 시퀀스 자동 설계
|
|
- Gemini TTS로 나레이션 음성 생성 (여성/남성/아이, 30종 음성, 속도 조절)
|
|
- Lyria RealTime WebSocket으로 AI 배경음악 실시간 생성
|
|
- 시퀀서/BGM 상호 배타적 재생 + TTS 공통 합성
|
|
- WAV 내보내기
|
|
|
|
---
|
|
|
|
## 2. 아키텍처
|
|
|
|
### 2.1 3레이어 오디오 구조
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Layer 1: 사운드 로고 (시퀀서 또는 AI BGM — 상호 배타적) │
|
|
│ ├── A) 시퀀서 (수동 편집 / 프리셋 / AI 생성) │
|
|
│ └── B) AI 배경음악 (Lyria RealTime) │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ Layer 2: 음성 TTS (Gemini) ─── 양쪽 모드 공통 │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ DynamicsCompressor (클리핑 방지) → AudioContext.dest │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
- **시퀀서 모드**: 수동/프리셋/AI 생성 음표 + TTS 합성. BGM 제외.
|
|
- **BGM 모드**: AI 배경음악 + TTS 합성. 시퀀서 음표 제외.
|
|
- 판단 기준: `bgmBuffer` 존재 여부
|
|
|
|
### 2.2 기술 스택
|
|
|
|
| 계층 | 기술 | 설명 |
|
|
|------|------|------|
|
|
| 프론트엔드 | Blade + Alpine.js | 단일 SPA |
|
|
| 오디오 엔진 | Web Audio API | OscillatorNode, BufferSourceNode, DynamicsCompressorNode |
|
|
| AI 시퀀서 | Gemini 2.5 Flash | 프롬프트 → JSON 음표 시퀀스 |
|
|
| TTS | `gemini-2.5-flash-preview-tts` | 30종 음성, Director's Note 스타일 제어 |
|
|
| BGM | Lyria RealTime (WebSocket) | `models/lyria-realtime-exp`, 48kHz 스테레오 PCM |
|
|
| 저장 | 없음 (클라이언트 전용) | WAV 내보내기로 결과물 보존 |
|
|
|
|
---
|
|
|
|
## 3. 시퀀서 (Layer 1-A)
|
|
|
|
### 3.1 입력 모드
|
|
|
|
| 모드 | 설명 |
|
|
|------|------|
|
|
| **수동** | 음표 그리드에서 직접 추가/삭제/편집 |
|
|
| **프리셋** | 사전 정의된 사운드 패턴 선택 (기업 시그널, 알림음 등) |
|
|
| **AI 생성** | 프롬프트 입력 → Gemini가 음표 시퀀스 JSON 반환 |
|
|
|
|
### 3.2 음표 데이터 구조
|
|
|
|
```json
|
|
{
|
|
"type": "note | chord | rest",
|
|
"note": "C5",
|
|
"chord": ["C4", "E4", "G4"],
|
|
"duration": 0.2,
|
|
"velocity": 0.8
|
|
}
|
|
```
|
|
|
|
### 3.3 신디사이저 설정
|
|
|
|
| 파라미터 | 범위 | 설명 |
|
|
|---------|------|------|
|
|
| `synth` | sine, triangle, square, sawtooth | 파형 |
|
|
| `volume` | 0~1 | 마스터 볼륨 |
|
|
| `adsr.attack` | 1~500ms | 어택 |
|
|
| `adsr.decay` | 10~1000ms | 디케이 |
|
|
| `adsr.sustain` | 0~1.0 | 서스테인 |
|
|
| `adsr.release` | 10~3000ms | 릴리즈 |
|
|
| `reverb` | 0~1 | 리버브 양 |
|
|
|
|
---
|
|
|
|
## 4. 음성 오버레이 — TTS (Layer 2)
|
|
|
|
### 4.1 음성 카테고리
|
|
|
|
| 카테고리 | 음성 수 | 주요 음성 |
|
|
|---------|---------|----------|
|
|
| **여성** | 9종 | Kore(단정), Aoede(산뜻), Leda(따뜻), Zephyr(차분) 등 |
|
|
| **남성** | 9종 | Puck(밝음), Charon(깊음), Orus(안정), Fenrir(무게) 등 |
|
|
| **아이** | 5종 | Leda 기반(여아), Puck 기반(남아) 등 |
|
|
|
|
### 4.2 속도 조절
|
|
|
|
| 단계 | Director's Note |
|
|
|------|----------------|
|
|
| 1 (매우 느림) | "아주 천천히 또박또박 말해주세요." |
|
|
| 2 (느림) | "조금 느린 속도로 말해주세요." |
|
|
| 3 (보통) | (지시문 없음) |
|
|
| 4 (빠름) | "조금 빠른 속도로 말해주세요." |
|
|
| 5 (매우 빠름) | "아주 빠른 속도로 말해주세요." |
|
|
|
|
### 4.3 오디오 형식
|
|
|
|
- 출력: `audio/L16;rate=24000` (16-bit PCM, 24kHz, 모노, little-endian)
|
|
- 디코딩: `DataView.getInt16(offset, true)` → Float32 변환
|
|
|
|
---
|
|
|
|
## 5. AI 배경음악 — Lyria (Layer 1-B)
|
|
|
|
### 5.1 WebSocket 프로토콜
|
|
|
|
```
|
|
브라우저 ──WebSocket──→ Google Lyria RealTime API
|
|
(wss://generativelanguage.googleapis.com/ws/...BidiGenerateMusic)
|
|
```
|
|
|
|
서버는 API 키만 전달(`GET /lyria-config`), 실제 WebSocket 통신은 브라우저에서 직접 수행한다.
|
|
|
|
### 5.2 메시지 흐름
|
|
|
|
```
|
|
1. setup → { setup: { model: "models/lyria-realtime-exp" } }
|
|
2. (수신) ← { setupComplete: {} }
|
|
3. 프롬프트 → { clientContent: { weightedPrompts: [...] } }
|
|
4. 설정 → { musicGenerationConfig: { bpm, density, brightness, scale, temperature } }
|
|
5. 재생 → { playbackControl: "PLAY" }
|
|
6. (수신 반복) ← { serverContent: { audioChunks: [{ data: "base64..." }] } }
|
|
7. 정지 → { playbackControl: "STOP" }
|
|
8. (종료) ← WebSocket close
|
|
```
|
|
|
|
### 5.3 BGM 파라미터
|
|
|
|
| 파라미터 | 범위 | 설명 |
|
|
|---------|------|------|
|
|
| `bgmPrompt` | 텍스트 | 음악 분위기 설명 |
|
|
| `bgmBpm` | 60~180 | BPM |
|
|
| `bgmDensity` | 0~100 | 밀도 (0~1 변환) |
|
|
| `bgmBrightness` | 0~100 | 밝기 (0~1 변환) |
|
|
| `bgmScale` | C_MAJOR 등 | 음계 |
|
|
| `bgmDuration` | 5~60초 | 생성 길이 |
|
|
|
|
### 5.4 오디오 형식
|
|
|
|
- 출력: 16-bit PCM, 48kHz, 스테레오, little-endian
|
|
- WAV 헤더 감지 시 `decodeAudioData` fallback
|
|
|
|
---
|
|
|
|
## 6. API 엔드포인트
|
|
|
|
### 6.1 사운드 로고 (RdController)
|
|
|
|
| HTTP | URI | 메서드 | 설명 |
|
|
|------|-----|--------|------|
|
|
| GET | `/rd/sound-logo` | `soundLogo()` | 스튜디오 페이지 |
|
|
| POST | `/rd/sound-logo/generate` | `soundLogoGenerate()` | AI 음표 시퀀스 생성 (Gemini) |
|
|
| POST | `/rd/sound-logo/tts` | `soundLogoTts()` | TTS 음성 생성 (Gemini TTS) |
|
|
| GET | `/rd/sound-logo/lyria-config` | `soundLogoLyriaConfig()` | Lyria WebSocket 접속 설정 반환 |
|
|
|
|
### 6.2 CM송/나레이션 (CmSongController)
|
|
|
|
| HTTP | URI | 메서드 | 설명 |
|
|
|------|-----|--------|------|
|
|
| GET | `/rd/cm-song` | `index()` | 나레이션 목록 |
|
|
| GET | `/rd/cm-song/create` | `create()` | 나레이션 제작 |
|
|
| POST | `/rd/cm-song` | `store()` | 나레이션 저장 |
|
|
| GET | `/rd/cm-song/{id}` | `show()` | 나레이션 상세 |
|
|
| DELETE | `/rd/cm-song/{id}` | `destroy()` | 나레이션 삭제 |
|
|
| GET | `/rd/cm-song/{id}/download` | `download()` | 음성 파일 다운로드 |
|
|
| POST | `/rd/cm-song/generate-lyrics` | `generateLyrics()` | AI 가사 생성 (Gemini) |
|
|
| POST | `/rd/cm-song/generate-audio` | `generateAudio()` | TTS 음성 생성 |
|
|
|
|
### 6.3 CM송 데이터 모델
|
|
|
|
| 모델 | 테이블 | 설명 |
|
|
|------|--------|------|
|
|
| `CmSong` | `cm_songs` | 나레이션 (회사명, 업종, 가사, 음성파일) |
|
|
|
|
**저장 경로**: `tenant` 디스크 → `cm-songs/{tenant_id}/{filename}.wav`
|
|
|
|
---
|
|
|
|
## 7. 오디오 엔진 상세
|
|
|
|
### 7.1 마스터 출력 체인
|
|
|
|
```
|
|
각 소스 (Oscillator / BufferSource)
|
|
→ GainNode (개별 볼륨)
|
|
→ DynamicsCompressorNode (마스터 리미터)
|
|
→ AudioContext.destination
|
|
```
|
|
|
|
**컴프레서 설정:**
|
|
- threshold: -6dB
|
|
- knee: 10dB
|
|
- ratio: 12:1
|
|
- attack: 3ms
|
|
- release: 150ms
|
|
|
|
### 7.2 WAV 내보내기
|
|
|
|
`OfflineAudioContext`로 오프라인 렌더링 후 `bufferToWav()` 변환.
|
|
- 샘플레이트: 44,100Hz
|
|
- 채널: 2 (스테레오)
|
|
- 비트: 16-bit PCM
|
|
- 오프라인 컨텍스트에도 동일한 DynamicsCompressor 적용
|
|
|
|
---
|
|
|
|
## 8. 관련 파일
|
|
|
|
| 파일 | 설명 |
|
|
|------|------|
|
|
| `resources/views/rd/sound-logo/index.blade.php` | SPA 뷰 (Alpine.js, ~2100줄) |
|
|
| `app/Http/Controllers/RdController.php` | 사운드 로고 API (4 메서드) |
|
|
| `app/Http/Controllers/Rd/CmSongController.php` | CM송/나레이션 CRUD (8 메서드) |
|
|
| `app/Models/Rd/CmSong.php` | CM송 모델 |
|
|
| `app/Helpers/AiTokenHelper.php` | Gemini 토큰 사용량 추적 |
|
|
|
|
---
|
|
|
|
## 관련 문서
|
|
|
|
- [R&D 메뉴 개요](README.md) — R&D 전체 메뉴 구조
|
|
- [AI 분석 리포트](../ai/README.md) — Gemini API 활용 패턴 참고
|
|
- [사운드 로고 생성기 기획서](../../plans/sound-logo-generator-plan.md) — 초기 기획
|
|
|
|
---
|
|
|
|
**최종 업데이트**: 2026-03-08
|