# 개발 세션 진행 로그 (PROGRESS)

> 이 문서는 **실제 빌드/실행 개발 세션**에서 진행한 내용을 기록한다.
> 설계·선생성 범위는 `PREBUILT.md`·`DEV_PLAN.md` 참조. 여기는 "미컴파일 선생성 → 실동작"으로
> 전환하며 실제로 검증/수정한 것과 **다음에 할 일**을 담는다.
> 최종 갱신: 2026-07-01

---

## ✅ 이번까지 완료 (실동작 검증됨)

### 빌드 / 실행
- 솔루션 빌드 성공(오류 0). `dotnet build src/DansoriEQ.App` 정상.
- WPF-UI **Fluent 다크테마 + Mica 배경** 적용 확인.
- **주의(빌드 함정)**: 앱 실행 중이면 `bin\Debug\...\DansoriEQ.Core.dll` 복사 단계가 **파일 잠금(MSB3021/3027)**으로 실패한다.
  → 빌드 전 반드시 `DansoriEQ.App` 프로세스를 종료할 것. (컴파일 자체는 통과, 복사만 실패하므로 착각 주의)

### AI (M4/M10)
- **Gemini 무료 API로 자연어 → EQ 적용 동작 확인.** (`aistudio.google.com` 키)
  - `GeminiProvider`가 `responseMimeType: application/json`으로 구조화 출력.
  - 프롬프트창 → provider → `EqDeltaApplier` → APO 적용 실배선 동작.
- Claude API는 사용자 계정 이슈(크레딧 충전 비활성)로 **보류**, Gemini로 테스트 진행.
- 만족도(EQ 품질) 평가는 사용자가 **추후 별도 진행** 예정.

### 프로파일 DB (M2)
- **AutoEQ SQLite 다운로드/적재 동작.** `UpdateAsync` 청크 다운로드(128KB) + 불확정 진행률(-1) 처리로 "멈춤" 오해 해소.
- 사이드바 **IEM / 헤드폰 2분할** 표시(그리드 2행).

### APO 연동 (M3)
- `ApoConfigInstaller` 신설: `config.txt`에 **`Include: ai_eq.txt`** 자동 추가(직접 쓰기 → 실패 시 승격 PowerShell 폴백).
- 최초 연동 안내 모달 **`ApoLinkWindow`**(다크 모던 UI)로 통일.
- 사용자가 **APO Configurator에서 자기 출력장치(DAC)**를 선택해야 실제 적용됨을 확인(가이드 완료).
- 실제 EQ 적용 동작 확인(활성 체크/바이패스 배선 포함).

### 창/헤더 UI
- **타이틀바(`ui:TitleBar`)** 추가 → 창 이동 가능.
- 헤더 버튼(설정/이펙트/되돌리기/리셋/⋯/활성)이 **기기 이름을 가리던 문제** → 헤더 Grid 2열 분리로 해결.
- `ACTIVE FILTERS` 박스 잘림 → ScrollViewer 패딩을 내부 StackPanel 마진으로 이동해 해결.
- 창 크기 확대(1400×860).

### EQ 밴드 편집 팝업 (M7 핵심) — 신규
- 필터 칩 **더블클릭 → 자체 그래픽 편집 팝업**(외부 APO 실행 아님). PowerAmp/Peace 지향.
- **전체 필터 타입 18종** 지원 (드롭다운):
  Peak / Low Pass / High Pass / Band Pass / Low Shelf / High Shelf / Notch / All Pass /
  Low·High Shelf(Slope dB) / Low·High Pass Butterworth(짝수차) /
  Low·High Pass Linkwitz-Riley(짝수차) / Low·High Shelf(Q as Slope) /
  Low·High Shelf(Corner Freq, Q as Slope).
  - `FilterType` 열거형 + 메타(`UsesGain`/`ThirdParam`/`DisplayName`/`ShortLabel`/APO 토큰) 확장.
  - `Filter.cs`: RBJ 바이쿼드 + **Butterworth/LR 폐형식** + 슬로프 셸프 수학 구현.
  - `ApoRenderer`: 타입별 정확한 APO 라인 + **Butterworth/LR은 2차 섹션 캐스케이드**로 전개.
- **컨텍스트 UI**: 타입에 따라 게인 숨김/표시, 3번째 컨트롤이 **Q / 기울기 / 차수**로 자동 전환.
- **Peace식 정밀 수치 입력**: 주파수·게인·Q/기울기/차수 각각 **입력창 직접 타이핑**(Enter/포커스이동 반영) + 슬라이더 + 그래프 3방향 동기화.
- **축 라벨(Hz/dB)을 그래프 컨트롤 내부에 로그/선형 실제 위치로 렌더** → 격자·라벨 정렬(이전 균등간격 라벨 오정렬 해소).
- **크래시 수정**: 생성자에서 `InitializeComponent()` 전에 `_editState` 미할당 상태로 이벤트가 발생해 NRE로 앱이 종료되던 문제 → 상태를 먼저 할당하도록 순서 수정. `App`에 **전역 예외 핸들러** 추가(이제 예외 시 종료 대신 오류창).

### 볼륨 / 출력장치 (M14)
- **하드웨어/디지털 하이브리드 볼륨** 구현.
  - 장치 선택 시 하드웨어 볼륨 지원 여부 **자동 프로브**.
  - 지원 → NAudio 엔드포인트 볼륨. 미지원(라인아웃 DAC) → **APO Preamp 디지털 감쇠**로 자동 전환(`SoftVolumeChanged` → `ApoRenderer.Render(volumeDb)`).
  - `ModeLabel`에 "하드웨어 볼륨 / 디지털 볼륨(APO)" 표시.
- **위험 요소 제거**: `DefaultDeviceSwitcher`(IPolicyConfig, 미검증 COM vtable) 호출 제거 — 오디오 손상 원인이었음. **재도입 금지.**
- 사용자 환경: **DAC 2대**. ① 라인아웃(헤드폰앰프 연결, 고정 레벨 → 하드웨어 볼륨 없음) ② 올인원(하드웨어 볼륨 O). 상세는 저장 메모 참조.

---

## 마스코트 UI (경로 A — WPF 네이티브) ✅ 진행 중
> 캐릭터(이소리·이단) 에셋을 앱에 결합. 방침=경로 A(WPF Storyboard/도형) → 필요한 곳만 경로 B(Lottie). `Characters/`.
- **AI 아바타**(`MascotAvatar`): 눈 깜빡임·말하기(프레임 교체)·부유. AI 응답 대기 중 말하기.
- **음파 링**(`SoundwaveRings`) + **EQ 막대 생각중**(`EqBarsFx`): AI 처리 중 연출.
- **성공 토스트**(`MascotToast`): 이단 thumbs-up 팝인, 명령창 위 중앙.
- **로딩**: `EqBarsFx`를 DB 업데이트 진행에 재사용.
- **온보딩**: 도움말 드로어에 이소리·이단 듀오.
- **스플래시**(`SplashWindow`): 시작 시 듀오 브랜드, 자동 페이드.
- **팝업 네온 테두리**: `App.xaml`의 `NeonPopup` 스타일 + Grid창은 오버레이 프레임 → 다크 배경에서 팝업 분리감.
- **이미지 투명화**: `tools/make_transparent.py`(색상키, 폐기) → **rembg(U²-Net) 재처리**가 최선. 원본 `Characters/_opaque_backup/`.
  - ⚠️ **이소리 헤어의 얇은 밝은 테두리(림라이트)는 원본 아트 특성** → 후처리 한계. **완전 제거는 투명 네이티브로 재생성 필요**(향후).
- **DB 창 모던화**: `DbManagerWindow` → FluentWindow+TitleBar. 업데이트는 **upsert(name,source)로 중복 없음**(단 매번 전체 재다운로드 — 캐시 최적화는 선택).

## ⚠️ 알려진 이슈 / 보류
- **라인아웃 DAC 볼륨**: 하드웨어가 소프트웨어 볼륨을 원천 미지원(Windows 믹서도 무반응 확인). 디지털(APO) 폴백은
  **해당 DAC에 APO가 설정돼 있어야** 동작. 사용자 요청으로 **추후 재검토**.
- **크로스피드 렌더는 여전히 플레이스홀더**(`ApoRenderer` 메모: 저역통과+딜레이 정식 구현 필요).
- All Pass 필터는 진폭 평탄(위상만) → 그래프에서 평탄선이 **정상**.
- Corner-Freq 셸프 변형은 미리보기에서 중심주파수를 코너로 **근사**.

---

## ▶ 다음에 할 일

### 1) 그래프 도트(노드) 위치 정상화  ← ✅ **완료(사용자 모니터링 중, 2026-07-02)**
**해결**: 노드를 **합성 곡선(보이는 실선) 위**에 배치(`ShapeDbAt(Fc)`). 드래그는 좌우=Fc(전 타입),
상하=게인(게인 있는 타입만, 상대/델타 방식). 게인 없는 타입은 상하 드래그로 게인 안 생김.
메인 그래프 + 편집 팝업 **동일 규칙** 적용. `EqGraphControl.cs`(OnRender/HitNode/OnMouseMove).
> 아래는 당시 원인 분석(참고용, 히스토리).

**현상**: 그래프의 필터 노드(동그라미)가 곡선과 어긋난 위치에 그려지는 경우가 있음.

**원인 분석**(코드 기준):
- `EqGraphControl`은 모든 노드를 **`(HzToX(Fc), DbToY(GainDb))`** 위치에 균일하게 그린다.
- **Peaking**: Fc에서 곡선 정점 ≈ GainDb → 노드가 곡선 위에 얹힘(정상).
- **셸프(LS/HS 등)**: Fc에서 곡선값은 대략 **GainDb/2**(중간점)인데 노드는 GainDb에 → 곡선보다 위에 뜸.
- **게인 없는 타입**(LP/HP/BP/Notch/AP/Butterworth/LR): `GainDb=0` → 노드가 0 dB 라인에 있는데
  실제 곡선은 컷오프에서 내려감 → 노드가 곡선에서 떨어짐.
- 편집 팝업의 **메인 실선 곡선은 전체 필터 합성**이라, 개별 노드가 합성 곡선 위에 없을 수 있음.

**해결 방향(택1, 다음 세션에서 확정)**:
- (A) 노드 Y를 **해당 필터의 자기 응답값 at Fc**(개별 곡선 높이)로 배치 → 항상 자기 곡선 위.
- (B) 노드 Y를 **합성 곡선값 at Fc**로 배치 → 메인 실선 위에 얹힘(Peace 유사).
- 드래그 시맨틱 정리: 게인 있는 타입은 상하=Gain, 게인 없는 타입은 **상하 드래그 비활성 또는 Q/차수 매핑** 고려.
- 메인 화면 그래프와 편집 팝업 그래프 **동일 규칙** 적용.

**관련 파일**: `src/DansoriEQ.App/Controls/EqGraphControl.cs` (OnRender 노드 그리기 / HitNode / OnMouseMove).

### 2) 이후(우선순위 낮음)
- 라인아웃 DAC 볼륨 UX 재정리(APO 폴백 안내 강화).
- LiveCharts2 vs 커스텀 캔버스 최종(M5). 현재 커스텀 캔버스 유지 중.
- AI EQ 품질 만족도 평가(사용자) 반영.
