볼륨 증폭기 (마이크 auto-gain) — 코드레벨 동작 흐름 P2코드레벨

마지막 업데이트 2026-07-29

볼륨 증폭기 (마이크 auto-gain) — 코드레벨 동작 흐름 P2 코드…: 입력: 개요 · 범위, 주요 처리 단계: 라이프사이클 · 상태, 결과: 파일 · 라인 레퍼런스 흐름
동작 흐름 요약
  1. 입력: 개요 · 범위
  2. 주요 처리 단계: 라이프사이클 · 상태
  3. 결과: 파일 · 라인 레퍼런스
작성일: 2026-06-14 대상: 개발자 — 내장 마이크 자동 게인 파악 핵심 파일: hooks/use-volume-amplifier.ts
💬 대화로 먼저 이해하기 — "음향 엔지니어 비유" (비개발자·처음 읽는 사람용)
Q아동 목소리가 너무 작게 들어오면 어떻게 하나요?
A공연장 음향 엔지니어가 가수 목소리가 작으면 믹서 페이더를 올리는 것과 같아요. 여기서는 GainNode가 페이더 역할이고, 마이크 소리 크기(RMS)를 계속 재다가 목표 레벨(-15dB)까지 자동으로 끌어올려요.
Q그럼 조용할 때 잡음까지 같이 커지는 거 아닌가요?
A그래서 엔지니어가 함부로 손대지 않아요. "지금 실제로 말하고 있는 순간"(-50dB 이상)만 골라 5번 모아 평균을 내고, 그 평균이 정말 작을 때(-35dB 미만)만 올려요. 무음이나 잡음에는 페이더를 건드리지 않죠.
Q모든 마이크에 이렇게 해 주나요?
A아니요. 자체 앰프가 달린 외장 마이크는 손대지 않고, 소리가 원래 작은 노트북·태블릿 내장 마이크일 때만 개입해요.
Q한 번 올린 볼륨은 계속 유지되나요?
A목소리가 정상 레벨로 돌아오면 페이더를 원위치(1.0)로 되돌리고, 조절 직후엔 30초 쉬면서 과도한 재조정을 막아요. 세부 조건과 부작용은 아래 "함정 · 주의" 섹션과 use-volume-amplifier.ts를 보세요.

개요 · 범위

아동 마이크 입력이 너무 작을 때 자동으로 게인을 올려주는 Web Audio 보정. 노트북/태블릿 내장 마이크처럼 입력 레벨이 낮은 기기에서 핑퐁이가 아동 음성을 잘 인식하도록 돕는다.

적용 조건: 세션 매니저(#1)의 createMediaStream에서 내장 마이크일 때만 적용(!audioInputDevice || isBuiltInDevice(...)). 외장 마이크는 자체 게인이 충분하다고 보고 건너뛴다. 적용 시 오디오 처리 체인(#7)보다 앞단.

노드 그래프 processMediaStream L168

source → analyser(FFT 2048) → gainNode(기본 1.0) → destination → processedStream

analyser로 RMS를 재고, gainNode 값을 동적으로 조절한다. 실패 시 원본 stream 반환(graceful).

자동 게인 로직 monitorVolumeAndDetectSpeech L109

파라미터: 목표 -15dB / 증폭 임계 -35dB / 발화 절대 임계 -50dB / 필요 세그먼트 5개 / 샘플 100ms / 분석 윈도우 300ms / 재시작 30s
  1. 300ms 윈도우 동안 100ms마다 RMS(dB) 샘플 수집 → 평균(currentVolumeDB).
  2. 평균이 -35dB 이상(정상)이면 resetGain()(게인 1.0 복귀).
  3. 평균이 -50dB 이상(발화로 간주)이면 발화 세그먼트로 누적.
  4. 발화 세그먼트가 5개 모이면 adjustGainBasedOnAverage(): 평균이 -35dB 미만이면 gain = 10^((-15 - 평균)/20)로 목표(-15dB)까지 끌어올림.
  5. 조절 후 모니터링을 멈추고 30초 뒤 재시작(과도한 재조정 방지).
// 게인 계산 (adjustGainBasedOnAverage)
gainAdjustment = TARGET(-15) - averageVolume
gainValue = Math.pow(10, gainAdjustment / 20)   // dB → 선형 배율
두 임계의 역할: -50dB(절대 발화 임계)는 "지금 말하고 있나"를 거르는 게이트, -35dB(증폭 임계)는 "증폭이 필요한가"를 판정. 무음/잡음에 게인을 올리지 않도록 발화 세그먼트 5개를 모아 평균으로만 조절.

라이프사이클 · 상태

메서드역할
processMediaStreamAudioContext+그래프 구성, processedStream 반환(실패 시 원본)
startVolumeMonitoring세션 확립 후 모니터링 시작(#1에서 호출)
stopVolumeMonitoring / cleanup인터벌·타이머 정리, AudioContext close
getStatus / setOnStatusChange증폭 상태(isAmplified, gainValue) 조회/콜백

상태 변화는 콜백으로 통지 → 게스트 릴레이(#6)가 guest-volume-amplifier-status로 호스트에 미러링(모니터 UI 표시).

함정 · 주의

  • 내장 마이크 한정: 외장 기기엔 적용 안 됨(#1의 shouldUseVolumeAmplifier 게이트). 모든 기기에 켜고 싶다면 호출부 조건을 바꿔야 함.
  • 증폭기 → 처리 체인(#7) 순서: 증폭기 출력이 DSP 체인 입력. 둘 다 별도 AudioContext라 체인이 두 단계.
  • 5세그먼트·30초 재시작: 반응이 느리게 느껴질 수 있으나 무음 오증폭·발진 방지용. 파라미터 변경 시 잡음 증폭 위험.
  • resetGain 조건: 정상 레벨(-35dB↑) 복귀 시에만 1.0으로. 안 그러면 한 번 올린 게인이 계속 유지될 수 있음.

파일 · 라인 레퍼런스

파일/심볼역할
use-volume-amplifier.ts (monitorVolumeAndDetectSpeech L109, adjustGainBasedOnAverage L65)auto-gain 본체
use-session-manager.ts:996–1034내장 마이크 시 processMediaStream 호출
lib/audio-utils.ts (isBuiltInDevice)내장 마이크 판정