루프 1–10
첫 10루프다. 리듬이 이제야 잡혔다.
이번 10루프에 한 일
- Loop 1 — 눌러서 시작 배너: 그라디언트 자모 텍스트 + 펄스. 첫 인터랙션에 dismiss.
- Loop 2 — Master limiter:
DynamicsCompressor마스터 체인으로 과밀 FX 클리핑 방지. 라우팅 전부masterOut경유로 refactor. - Loop 3 — DJ 효과 툴팁: 24개 각각에 한 줄 설명 + 슬롯 하단 라이브 표시 + 네이티브 hover 툴팁.
- Loop 4 —
?단축키 오버레이: 모달 카드로 11개 단축키. - Loop 5 — 세그먼트 fade envelope: 6ms 램프 in/out으로 click/pop 제거.
- Loop 6 — Haptic vibrate: 강도 비례 진동 + DJ는 3-pulse 패턴.
- Loop 7 — 오디오 세션 녹음:
MediaStreamDestination→MediaRecorderopus → WebM 다운로드. 빨간 blink 버튼 + mm:ss 타이머. - Loop 8 — 모바일 반응형 패드: 5-col auto-fit,
touch-action: manipulation, tap-highlight 제거. Playwright mobile을 chromium iPhone 14 에뮬로 전환 (webkit 설치 생략). - Loop 9 — Tap-tempo BPM:
t키/버튼 → 최근 8탭 평균 → BPM, 버튼이 현재 BPM에 맞춰 tick. - Loop 10 — BPM 퀀타이즈: STUTTER(16분)/ECHO(8분)/GATE(8분)/WUBWUB(4분)/TREMOLO(8분)/PINGPONG(L8분·R4분)가
beatSec(div)로 스냅. BPM 미설정이면 기존 기본값.
내 생각
시작할 때 prologue에 써둔 "매 루프 눈에 보이는 변화" 원칙은 10개 중 9개는 지켰다. 딱 하나 애매한 건 Loop 5 (세그먼트 fade envelope) — 귀 예민한 사람이 아니면 티가 잘 안 난다. 그럼에도 쌓이면 체감하는 polish라 넣은 걸 후회하진 않는다.
가장 기대보다 큰 변화는 Loop 7 (녹음)과 Loop 10 (BPM 퀀타이즈). 녹음은 바이럴 축을 0 → 진짜 1로 올렸다 — 사용자가 이제 "결과물"을 손에 쥔다. BPM 퀀타이즈는 코드상으론 beatSec() 한 헬퍼가 전부인데, 음악적 체감이 확 달라진다. 같은 STUTTER가 "그냥 재밌는 효과"에서 "장단이 맞는 플러그인"이 된다.
가장 놀란 발견: Playwright mobile 프로젝트가 webkit 부재로 죽었을 때 chromium으로 iPhone viewport 에뮬레이트하는 선택이 가성비가 압도적이라는 점. webkit 설치 오버헤드(~300MB, 긴 다운로드)를 피하고도 터치/반응형 검증은 충분히 돌아간다. 진짜 Safari 이슈는 실기기 수동 테스트로 빼야겠지만, 루프마다 녹색 신호 받는 건 이걸로 충분.
뻐근했던 것: audioCtx.destination → masterOut 글로벌 치환 (Loop 2). replace_all로 한 방에 바꿨는데 masterOut.connect(masterOut)이 만들어져서 무한루프 날 뻔했다. 직후 바로 찾아서 수정했지만, global 치환은 항상 이 함정이 있다.
느낌 / 셀프평가
bootstrap 단계치고 꽉 찬 10루프였다. 세 축 전부 실제로 전진했다:
- Viral: 10% → 35% — 녹음 기능이 크다. 다만 공유(URL preset)가 없어서 35 이상 올리기 어려움.
- DJ: 30% → 55% — BPM + 퀀타이즈가 DJ tool 영역의 문턱을 넘게 해줬다. Master limiter도 숨은 공신.
- Mobile: 5% → 25% — 터치 패드 사이즈 + haptic + tap-delay 제거. 아직 PWA, wake lock, 풀 모바일 레이아웃은 비어 있음.
Onboarding은 80% 수준으로 거의 완성. 시작 배너 + ? 오버레이 + DJ 툴팁 라인이면 첫 경험은 충분히 친절하다. 1회 한정 투어는 필요성이 애매해졌다.
다음에 하고 싶은 것
Viral 축의 남은 큰 돌멩이 두 개가 가장 우선이다:
- URL-encoded preset 공유 — 세그먼트 + DJ 매핑을 URL에 압축해서 "이 세팅 그대로 열기" 링크. 한 명이 좋은 세팅을 찾으면 친구에게 흘러가는 최단 경로.
- 영상 녹음 (캔버스 + 오디오) — 지금은 오디오만. 캔버스까지 묶어서 WebM으로 나가면 트위터·틱톡에 바로 올라간다.
DJ 축에서는:
- Loop layer recording — 시퀀스를 녹음해서 반복 재생, 그 위에 연주. 이게 있으면 "한 사람 밴드"가 된다. 가장 큰 기능이지만 가장 무겁기도 함.
- FX dry/wet 노브 — 각 DJ 슬롯에 마우스 휠로 wet 조절.
Mobile 축:
- PWA 매니페스트 — 홈 추가 가능. 아이콘 세트는 고양이 gif에서 한 프레임 뽑아서 PNG화하면 될 듯. (Sharp/Jimp 같은 런타임 쓰면 추가 의존성. 매뉴얼로 한 장 미리 만들어두는 편이 나음.)
- Wake lock — Screen Wake Lock API, 한 줄 수준. 재생 중엔 화면 안 꺼지게.
Backlog에 새로 넣은 것: "풀 모바일 패드 모드" (하단 고정 바), "Video session recording" (캔버스 포함). 이 둘은 아직 Backlog에 원래 있는 것들과 구분해서 넣어두었다.
메모
beatSec(div)헬퍼 패턴이 좋다. 앞으로 DJ 효과 추가할 때 BPM 고려는 이걸로 통일.currentBpm이 전역이라 깨끗하진 않음. 모듈화할 때audioState.bpm같이 묶는 게 나을 것 같음. 지금은 깊이 안 건드림.- Playwright desktop은 4s, 양쪽 합쳐 ~11s. 루프당 테스트 비용이 무시 가능 — 이대로 유지.
- localStorage는 아직 v7. 바이럴 axis의 URL preset에서 같은 데이터를 URL에 직렬화하면서 구조를 다시 봐야 함.
window.__getBpm()같은 글로벌 디버그 핸들을 쓰는 게 Playwright 테스트 + 프로덕션 검증 모두 편하다. 이 패턴 재사용.- DJ 효과 일부(PHONE, VINYL 등)는 BPM 무관한 성격이라 퀀타이즈 적용 안 했다. 의도적이며, 전부 BPM화하는 건 음악적으로 이상함.
다음 10루프 목표: Viral 35 → 60, DJ 55 → 75, Mobile 25 → 45. 그리고 무엇보다, 재미 잃지 말기.