AudioContext·오디오 graph 재활용 — iOS 렌더 밀림 완화 설계 공유 ctx 개선안 철회

마지막 업데이트 2026-09-11

공유 AudioContext 개선안은 덕킹 문제로 2026-09-10 철회했다. 아래는 철회 전 Context·graph 재활용 제안과 로그 분석 근거를 보존한 기록이며, 현재 권장안은 OFF 처리 노드 우회를 우선하는 최소 변경 완화 설계다.

작성일: 2026-09-03 상태: 공유 ctx 개선안 철회(2026-09-10) · 이전 설계 기록 범위: 게스트 Web Audio/LiveKit 입력 처리
공유 ctx 개선안 철회 · 2026-09-10. 덕킹 문제에 따른 사용자 결정이다. 아래 제안은 이전 검토 기록으로 보존하며, 현재 구현 지침은 PPI-1290 · iPad AI 음성 밀림 — 최소 변경 완화 설계를 따른다. 후속안 역시 코드 미반영·개선 효과 미검증이다.

한 줄 결론

활동·스텝·LiveKit 재접속마다 AudioContext와 graph 전체를 닫고 다시 만드는 대신, Context와 정적 처리 노드를 유지하고 source track/publication만 교체한다. 이번 사건의 로그와 정합하는 완화 실험이지만, 네트워크·iOS AudioSession·단말 열/CPU 부하를 자동으로 해결한다는 뜻은 아니다.

이 문서는 홍윤우 1회기 “지지직” 분석에서 제안된 재활용 방법을 독립적으로 정리한 설계·검증 가이드다. 현재 구현이나 배포 결과를 기록한 문서가 아니며, 먼저 계측과 동일 기기 A/B 검증을 거쳐야 한다.

2026-09-10 실기기 실험 반영. 게스트 디버그 하네스로 AudioContext를 255개까지 누적해도, 렌더 콜백을 40% 누락시켜도 정상 전원에서는 AI 음성이 밀리지 않았다. 밀림은 저전력 모드 + WebAudio 렌더 부하가 함께 있을 때만 재현됐다(저전력 단독은 정상). 따라서 이 문서의 재활용 제안은 “Context 개수·재생성 자체가 지연을 만든다”가 아니라 저전력 단말에서 WebAudio 총 렌더 부하를 임계 아래로 낮추는 수단으로 읽어야 하며, 우선순위는 상시 렌더 연산(loopback 믹싱·입력 체인·analyser)이 중복되지 않게 하는 쪽이다. 실험 상세는 iPad AI 음성 밀림 재현 — 저전력 모드 × WebAudio 렌더 부하.

1. 왜 재활용을 검토하는가

시각(KST)관찰해석 범위
20:33:22~20:37:27첫 graph health의 벽시계 대비 currentTime 진행률 약 1.000같은 세션 앞부분은 정상 진행
20:37:32 이후LiveKit disconnect 직후 graph 재생성. 이후 진행률 약 0.913재접속·재생성과 drift가 시간상 인접
20:43:45 이후새 graph 진행률 약 0.816동일 현상이 재생성 뒤 반복
20:46:50 이후새 graph 진행률 약 0.813lifecycle 관여 가능성 보강

게스트 로그의 Audio chain health 194건은 모두 state=running, currentTimeAdvanced=true, processed/relay track live였다. 그러나 현재 health 판정은 “조금이라도 전진했는가”만 보므로, 5초에 4.1초 진행하는 drift를 정상 health로 기록한다. 위 진행률은 로그의 벽시계 차분을 별도로 계산한 값이다.

2. 현재 구조와 바꿀 경계

AudioContext (페이지/오디오 세션 수명) └ source node (세션·track 교체 지점) └ gate → EQ → compressor → limiter → outputGain ├ agentDestination → AI 입력 publication └ relayDestination → 진행자 relay publication └ analyser → 레벨 측정 activity/step: AudioParam·입력 정책만 변경 LiveKit reconnect: source/publication만 교체 page/session permanent teardown: graph disconnect + context.close()

관련 코드의 LiveKitAudioChainProcessor.restart()는 graph를 destroy한 뒤 다시 build하는 구현이고, useAudioProcessingChain.processMediaStream()은 기존 Context를 close하고 새 Context를 만든다. 이는 재활용 불가능의 증거가 아니라 현재 lifetime 경계가 Context와 graph에 함께 묶여 있다는 뜻이다.

또한 이 처리 graph의 출력은 스피커용 audioContext.destination이 아니라 MediaStreamAudioDestinationNode 두 개다. 따라서 이 문서의 “렌더”는 우선 브라우저의 Web Audio 처리 graph가 실시간으로 진행되는지를 뜻하며, AI audio element의 실제 가청 출력과 동일시하지 않는다.

3. 제안 동작

  1. 생성: 사용자 제스처가 가능한 시점에 Context와 정적 처리 노드·destination을 한 번 만든다. Context 상태가 suspended면 같은 제스처에서 resume한다.
  2. 활동/스텝 전환: 새 Context나 graph를 만들지 않고 gate, gain, AI input enable 등 parameter와 정책 상태만 갱신한다.
  3. 재접속: 기존 Context·처리 노드는 유지하고 이전 source를 disconnect한 뒤 새 microphone track source만 연결한다. WebRTC가 새 publication을 요구하면 destination track의 publication만 갱신한다.
  4. 정리: 이전 source와 track을 중복 연결하지 않고 monitor timer를 하나만 유지한다. 페이지 종료·영구 세션 종료에서만 destination/track을 정리하고 Context를 close한다.
재활용은 무조건 적용하지 않는다. sampleRate·채널 수·graph topology가 바뀌거나 destination track이 ended 된 경우에는 해당 source/destination만 재구성할 수 있다. Context 전체 재생성은 복구 불가능한 오류나 영구 teardown으로 제한한다.

4. 함께 줄일 수 있는 비효율

항목제안주의점
20ms main-thread monitorRMS/VAD를 AudioWorklet로 옮기거나 50~100ms로 완화하고, 값이 변할 때만 setTargetAtTime 호출오디오 품질·gate 반응속도 회귀를 별도 측정
중복 DSPWebRTC AGC/NS/AEC와 Web Audio auto gain/EQ/comp/limiter의 중복을 확인하고 필요한 노드만 유지마이크 VAD·에코·음성 레벨에 직접 영향
재접속 media churnMediaSoup transport·camera/mic/AI producer 전량 재생성이 실제로 필요한지 effect dependency와 publication 계약을 확인서버 recording/relay가 새 track을 요구할 수 있음
진단 probethrowaway probe Context와 live processing Context를 구분하고, active Context의 drift를 직접 기록새 probe가 정상이어도 주 graph 정상의 증거는 아님

5. 검증 설계와 수용 기준

동일 iPhone·동일 iOS·동일 브라우저·동일 네트워크에서 다음 두 조건을 비교한다. 아래 기준은 제안된 판정 기준이며 아직 실기기에서 검증된 수치가 아니다.

조건Context/graph비교 지표
A현재 방식: 재접속 시 Context/graph 전체 재구성기준선
B개선 방식: Context·정적 노드 재활용, source/publication 교체완화 효과

6. 위험과 롤아웃 순서

  1. 계측만 먼저: Context identity, generation, delta/rate, statechange, source/destination lifecycle을 추가한다. 동작 변경 없이 정상 세션 기준선을 확보한다.
  2. feature flag A/B: iOS 한정 또는 내부 계정에서 B를 켜고 15분 이상 세션, 활동 전환, LiveKit 재접속, 출력 장치 전환을 반복한다.
  3. 단계적 확대: drift·gap·track publication 오류가 악화되지 않을 때만 범위를 넓힌다. source stale, duplicate audio, destination ended가 발생하면 즉시 A로 되돌린다.
이번 데이터셋의 미확정: render-underrun 카운터, 게스트 업링크 RTP 연속 통계, AI 독립 stem, 원본 OGG가 없어 재활용이 실제 원인인지와 실제 스피커 출력까지의 인과는 아직 확정할 수 없다.

관련 문서 · 코드