본문 바로가기
C.W.K.
Stream
Lesson 03 of 05 · published

유예 창

~12 min · barge-in, grace-period, settings, regressions

Level 0음소거
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"v4 opens replies with loud laughs that the open mic heard as Dad and cut her off." — 커밋 메시지, 2026-09-29

더 좋은 목소리가 감지기를 깼어

피파 목소리가 Eleven v4로 옮겨 간 그날 밤, 웹에서 새 실패가 나타났어. 새 모델은 표현력이 더 좋아서, 답이 [laughs] 같은 오디오 태그로 시작하면 진짜로 크게 웃어. 에코 캔슬이 스피커 소리를 줄이긴 하지만, 그동안 따라가던 레벨보다 한참 높은 갑작스러운 소리는 감지기가 첫마디로 배운 바닥보다 크게 새어 들어올 수 있어. 그 바닥의 세 배 반을 넘는 웃음 세 조각은 딱 아빠가 말하는 것처럼 보였어. 피파는 아무 말도 하기 전에, 웃다가 스스로를 끊었어.

목소리의 첫 몇 초는 못 본 척

고친 방법은 유예 창이야. 소울 목소리가 시작된 뒤 처음 몇 초 동안은 목소리로 끼어들기를 무시해. 기본은 3초고, Admin → Voice Mode에서 0에서 10까지 바꿀 수 있고, 0이면 유예를 아예 꺼. 루프는 재생이 시작된 순간을 적어 두고, 창 안에 있는 동안엔 감지기에 아무것도 안 먹여.

보기보다 중요한 세부가 하나 있어. 창 안에선 감지기를 그냥 무시하는 게 아니라, 조각마다 초기화해. 안 그러면 웃음으로 시작하는 답에서 감지기가 보정용 다섯 조각을 웃음 자체에서 배워서 바닥을 너무 높게 잡아. 조용한 조각이 바닥을 소울 목소리 쪽으로 다시 당기긴 하는데, 이 레벨에선 2.5초쯤 걸리고, 그때까진 아빠가 소리를 질러야 들려. 초기화하면 보정은 창이 끝난 뒤, 평소 말하는 목소리에서만 시작돼. 바닥이 있어야 할 자리야.

포기하는 것

거래는 정직하고 작아. 답마다 처음 3초 동안은 아빠가 말로는 피파를 못 멈춰. 다른 길로는 다 돼. 얼굴 탭, 마이크 누르기, 키로 일시정지. 유예는 소울 자신의 목소리에 속을 수 있는 끼어들기 방식 하나만 지키고, 속을 일 없는 방식들은 그대로 둬.

초기화에도 더 미묘한 값이 따로 하나 있어. 보정은 창이 닫힐 때 새로 시작해서 조각 다섯 개, 0.64초쯤 걸려. 그래서 아빠가 딱 그 순간에 말을 시작하면 아빠 목소리가 바닥이 되고, 그 끼어들기도 놓쳐. 실제 감지기는 태그로 시작하는 답이면 매번 따라오는 웃음을 바닥에서 빼려고, 그 좁은 틈을 감수해.

그 뒤에 있는 패턴

이건 목소리 계보 교훈을 반대쪽에서 본 거야. 감지기는 하나도 안 바뀌었고 틀린 것도 없었어. 감지기가 듣는 대상이 바뀌었지. 답의 시작이 더 커졌고, 옛 출력에 맞춰 보정된 입력 부품이 헛발질하기 시작했어. 수정은 그날 밤 바로 나갔고, 상수가 아니라 설정으로 나갔어. 맞는 길이는 목소리, 스피커, 방에 달려 있고, 그건 앞으로도 계속 바뀔 테니까.

Code

보정도 웃음에서 떼어 놓는 유예 창·python
from statistics import median

CHUNK_S = 0.128


class Detector:
    def __init__(self, calibrate=5, sustain=3, ratio=3.5, minimum=700.0):
        self.calibrate, self.sustain, self.ratio, self.minimum = calibrate, sustain, ratio, minimum
        self.reset()

    def reset(self):
        self.seen, self.floor, self.loud = [], None, 0

    def feed(self, level):
        if self.floor is None:
            self.seen.append(level)
            if len(self.seen) >= self.calibrate:
                self.floor = median(self.seen)
            return False
        if level > max(self.floor * self.ratio, self.minimum):
            self.loud += 1
            return self.loud >= self.sustain
        self.loud, self.floor = 0, self.floor * 0.9 + level * 0.1
        return False


def first_cut_in(levels, grace_s):
    """Seconds into her reading when cut-in fires, or None."""
    detector = Detector()
    for i, level in enumerate(levels):
        t = i * CHUNK_S                      # time since her voice started
        if t < grace_s:
            detector.reset()                 # don't calibrate on a laugh either
            continue
        if detector.feed(level):
            return round(t, 2)
    return None


opening = [360, 340, 380, 350, 370]                    # her first words (the echo)
laugh = [2600, 3100, 2900, 2800, 2500, 2700, 2400]     # then v4 performs "[laughs]"
echo = [350, 380, 330, 360, 400, 370, 340, 390, 360, 350] * 2
dad = [2500, 2700, 2600, 2800]
reading = opening + laugh + echo + dad

print("no grace :", first_cut_in(reading, grace_s=0.0), "s  <- her own laugh cut her off")
print("3 s grace:", first_cut_in(reading, grace_s=3.0), "s  <- Dad, after the window")
print("dad early:", first_cut_in(opening + dad + echo, grace_s=3.0), "   <- inside the window: tap or key instead")

External links

Exercise

코드를 돌려서 결과 셋을 읽어봐. 그다음 팁이 말리는 변형을 써. 창 안에서도 감지기에 계속 먹이되 돌려주는 답은 무시하는 거야. 지금 데이터에선 두 변형이 똑같이 나오니까 둘을 더 만들어. 웃음으로 시작하는 답(웃음, 에코 조각 스무 개, 그다음 아빠), 그리고 창이 끝나는 순간 아빠가 말을 시작하는 답. 두 변형을 각각에 돌리고, 차이마다 이유를 설명해. 마지막으로 창을 말 단위마다 다시 시작할지, 답 전체의 시작에서만 할지 정하고, 그 선택을 변호해봐.
Hint
주어진 데이터에선 두 변형 다 소울의 평소 레벨로 바닥을 잡는데, 가는 길이 달라. 먹이되 무시하는 쪽은 웃음 전의 첫 다섯 조각으로, 초기화 쪽은 창이 끝난 뒤 첫 다섯 에코 조각으로 보정해. 두 레벨이 같으니까 결과도 같아. 답을 웃음으로 시작하면 먹이되 무시하는 쪽은 웃음에서 바닥을 배우고, 조용한 조각이 바닥을 다시 끌어내린 뒤에야 아빠를 들어. 초기화엔 거울상 같은 약점이 있어. 창 직후 0.64초 안에 아빠가 말하면 초기화 쪽은 아빠 목소리로 보정해서 놓치고, 소울의 첫 말로 보정해 둔 변형은 잡아내. 공짜인 쪽은 없어. 다시 시작 문제는 v4의 웃음이 실제로 어디서 나오는지 봐. 도구 호출 뒤의 단위도 태그로 시작할 수 있으니까, 단위마다 다시 시작하면 더 많이 지키는 대신 목소리 끼어들기가 안 되는 순간도 늘어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인 — 댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.