← 목록
기타 2026-07-02 51KB 읽기 48분

크라우니음성인식도구 (Crowny STT) — 설계

voice.crowny.org:9971 · 크라우니LLM/SLM 베이스 · 4상균형3진논리를 구분점으로 후속: 같은 아키텍처로 OCR 확장 예정(모듈 5개 공유)

개요

한글 음성 → 텍스트(STT) 도구. 일반 STT가 신경망 softmax→argmax로 강제 확정하는 것과 달리, 크라우니 STT는 4상균형3진논리(T/O/A/U)로 음소 판정을 표현한다:

  • T(+1) 참·데이터 — 확신하는 음소 (에너지·정합 임계 초과)
  • A(-1) 거짓·체이닝 — 확신하며 기각한 후보
  • O(0) 모름·명령 — 음향증거 모호 (잡음·동음·웅얼거림) → 강제하지 않고 LLM이 문맥해소
  • U 구분자 — 음절/단어 경계
모름(O) 전파가 핵심 차별점이다. 전통 STT는 불확실해도 argmax로 찍어 오류가 뒤로 전파된다. 크라우니 STT는 불확실 음소를 O로 남겨 후보집합과 함께 크라우니LLM에 넘기고, LLM이 문맥으로 채운다(Kleene 3값 논리).

구분점(차별점) 5가지

#구분점내용근거
1모름(O) 전파argmax 강제 X. 불확실 음소=O 슬롯+후보집합 → LLM 문맥해소Kleene 3값, 조기확정 오류전파 차단
2음절경계 U한글 음절=초성+중성+종성 3분할 → 삼진 자연대응, U트릿=경계한글이 삼진구조와 동형
3삼진가중 음향모델BitNet식 트릿 가중치{-1,0,+1}, 곱셈기0(trit_dot), 티옴타 하드웨어 네이티브feedback_ternary_efficiency: 방어가능=15배+곱셈기0
4결정론적 자모조합자모→완성형 한글=유니코드 결정론 O(1)(수렴X)feedback_삼진구조는결정론: 구조=결정론, ML은 퍼지경계만
5신뢰도 3진맵 출력각 글자에 T/O/A 신뢰도 동반 → 다운스트림이 판단불확실성 투명화

파이프라인

[마이크/오디오 PCM 16kHz]
   ↓
[1] 전처리        프리엠퍼시스 + 프레임분할(25ms/10ms) + 해밍윈도우   ← 기존 한선씨 자산 재사용
   ↓
[2] 특징추출      FFT → 멜필터뱅크(26) → MFCC(13)                    ← 기존 한선씨 자산 재사용
   ↓ (실수 특징벡터)
[3] 삼진양자화    MFCC → 4상 트릿벡터 (|x|<θ_low→O, x>θ_hi→T, x<-θ_hi→A)  ★NEW 핵심
   ↓ (트릿 시퀀스)
[4] 음향모델(SLM) 크라우니SLM 삼진분류 → 음소후보 + 신뢰도트릿(T확신/O모름/A기각)  ★NEW
   ↓
[5] 삼진디코더    U(음절경계) 검출 + 빔서치. O자리는 후보집합 보존         ★NEW
   ↓ (부분확정 자모열 + 모름슬롯)
[6] 자모조합      초성×21×28+중성×28+종성 + 0xAC00 → 완성형 한글(결정론)   ★NEW
   ↓
[7] LLM결합       크라우니LLM이 O슬롯 문맥해소 + 문법·띄어쓰기 교정         ★NEW
   ↓
[출력]           최종 한글 텍스트 + 신뢰도 3진맵(글자별 T/O/A)

결정론 vs 퍼지 분리(메모리 원칙 준수):

  • 퍼지(ML/SLM) = [4] 음향모델 하나뿐. 오디오→음소의 자연스러운 경계만 학습.
  • 결정론(삼진규칙) = [3][5][6] 전부. 양자화 임계·빔서치·자모조합은 수렴 없는 O(1) 규칙.

모듈 (한선씨 라이브러리)

모듈파일상태역할
전처리음성전처리.한선재사용프레임분할·해밍윈도우·프리엠퍼시스
특징추출특징추출.한선재사용FFT·멜필터·MFCC (학습DB fn_음성인식_)
삼진양자화삼진양자화.한선★신규MFCC→4상 트릿 (구분점 핵심)
음향모델음향모델삼진.한선★신규SLM 트릿가중 음소분류(BitNet식)
자모조합한글음절조합.한선★신규자모→완성형 한글(유니코드 결정론)
디코더삼진디코더.한선★신규U경계·빔서치·O슬롯 보존
LLM결합LLM결합.한선★신규크라우니LLM 모름해소 인터페이스
오케스트레이터음성인식도구.한선★신규파이프라인 조립 + 서버(:9971)

크라우니LLM 결합 인터페이스

STT는 LLM에 3층 구조를 넘긴다:

{
  확정텍스트: "오늘 날씨가",
  모름슬롯: [ {위치:3, 후보:["좋","조","줗"], 신뢰:O} ],
  신뢰도맵: [T,T,T,O,...]
}
LLM은 문맥으로 모름슬롯을 채워 "오늘 날씨가 좋네요" 반환. 제약생성(constrained decoding)이되, 불확실성이 명시적 O로 전파되는 점이 일반 STT+LLM 후처리와 다름.

SLM 베이스 (크라우니SLM / 젯슨 토르)

  • 음향모델 = 트릿 가중치 신경망(BitNet 계열) → 곱셈기 제거, 티옴타 VM/토르 네이티브.
  • 나머지(양자화·디코더·조합) = 삼진 규칙엔진 → 토르가 재구축 수행(메모리 project_compound_ai_thor).
  • 방어가능 효율: 15배(BitNet) + 곱셈기0. 총배수는 FPGA 실측 전 주장 금지(메모리 이중계상 함정).

OCR 확장 (후속 — 모듈 공유)

같은 아키텍처. 이미지→특징→삼진양자화→SLM 문자분류→모름슬롯→LLM 문맥해소→자모조합. 공유 모듈: 삼진양자화·음향모델(문자모델로 교체)·삼진디코더·자모조합·LLM결합. STT를 지으면 OCR은 특징추출부([1][2])만 이미지용으로 교체.

잔여 이슈 / 다음 단계

  1. P0 계량화 먼저: 음향모델 정확도·모름율·LLM해소 성공률을 실측(스텁 방지 — 메모리 토르 교훈).
  2. 삼진양자화 임계(θ_low/θ_hi) 튜닝 = 모름율 제어 손잡이. 너무 높으면 전부 O(LLM부담), 너무 낮으면 강제확정(오류).
  3. 음향모델 학습데이터 = 한국어 음소 코퍼스 필요. 초기엔 규칙기반 포먼트 매칭으로 부트스트랩.
  4. 크라우니LLM API 계약 확정(모름슬롯 포맷).
  5. 실시간(스트리밍) vs 배치 — 1차는 배치(파일), 2차 스트리밍.

진행 로그

  • 2026-07-02 ①②③ 완료 (페블 세션): 음향모델삼진.한선(트릿내적 곱셈기0·음소분류 T/O판정)+삼진디코더.한선(U분할·다수결·O슬롯보존·자모조합)+LLM결합.한선(PSV 계약 v1: 작업/음소열/신뢰도맵/코드열/모름슬롯|위치|후보, 프롬프트생성·응답텍스트 파서) 구현.
  • E2E 검증 통과: 합성 MFCC 10프레임 → 음소열 ㅎ,ㅏ,? / 신뢰도맵 1,1,0 / 코드열 54616('하') / 모름슬롯|2|ㅏ,ㅣ — 모름(O)전파+결정론조합 구분점 실동 확인.
  • 적대검증(페블): ⑴ 맵꺼내 미존재키=-1(0 아님) → ==0 가드 전멸 버그 발견·수정·재검증(가드레일 템플릿 129행에 기존재 — 참조 누락이 원인). 기존 학습DB fn_음성인식_STT생성 동일버그 → 양쪽 DB 교정 완료. ⑵ 모름율 단위버그(모름수=차원단위/프레임수 분모 → >1000 가능) → 트릿총수 분모로 수정, 846/1000 정확 검증. ⑶ 잔여 리스크: FFT간단=O(N²) DFT(실시간엔 네이티브 opcode 필요), 멜필터=선형근사(정식 log 공식 아님), 부트스트랩 템플릿 4음소=토이(실코퍼스 학습 전), LLM 제약생성 미강제(응답이 후보 밖 음소 쓸 수 있음 → 서버측 후보검증 필수, 보상엔진과 같은 trustless 원칙).

2차 진행 — 실오디오·서버·P0 계량 (2026-07-02 오후)

  • WAV읽기.한선: RIFF 청크워크 파서(버퍼파일읽기 874 + 버퍼바이트읽기 851). 배열캡 4095 함정 → 버퍼 직접 프레임 스트림(WAV정보/WAV프레임/WAVMFCC추출)으로 재설계.
  • 특징추출.한선: 기존 학습패턴 조립 + 기존 FFT간단 패턴 실버그 발견(코사인값=사인/1000 정수화 → 스펙트럼 전멸) → 재작성(float 삼각함수 + 정모듈로 + 24트릿 오버플로 가드). 양쪽 학습DB 교체 완료. 프레임정규화(MAD 스케일) 신규.
  • VM 실측 추가: 정수 = 24트릿 균형3진 ±141,214,768,240(제곱 전 1e4 축소 필수) · %모듈로 자연반올림 깨짐(가드레일 기존재) · 버퍼읽기≠바이트(버퍼바이트읽기 851 사용).
  • 실오디오 E2E: say(Yuna) "하나" 0.41s → 200프레임 2.7s 처리, 정규화 MFCC 건강분포, 모름율 650/1000. 토이모델은 전부 O 판정 = 환각 대신 정직한 모름 선언(설계 의도). 모름슬롯 후보에 실제 음소(ㅎ/ㄴ/ㅏ) 포함.
  • P0 계량(합성 통제셋 32건): T정확도(강신호) 700/1000 · 오확정률 0/1000(강·모호 모두 — 설계 목표 달성) · O해소가능률 1000/1000(진실∈후보 → LLM 해소 가능).
  • 서버 라이브: :9971 (build.sh 조립빌드, 네트워크.한선 견고 패턴). /health·/api/stt(본문 경로|/abs.wav→PSV 페이로드) curl 검증 통과.

3차 진행 — 실코퍼스 음절 템플릿 학습 (2026-07-02 밤, 서브에이전트)

  • 코퍼스: say -v Yuna(140/180/220) × 8음절(하나이고미수오비) = 24 WAV 16kHz mono (scratchpad/corpus). 훈련=140+220, 테스트=180(미사용 홀드아웃).
  • tools/템플릿학습.한선: WAVMFCC추출→벡터양자화→비침묵 프레임 차원별 부호다수결(|합|>비침묵수/3)→13트릿 템플릿 8종 + 홀드아웃 평가 + lib 소스 자동생성.
  • libs/음소템플릿.한선: 학습된모델생성() — 부트스트랩모델생성()과 동일 구조, 음소분류/세그먼트요약 그대로 재사용. E2E 컴파일·자기분류 검증 통과, 학습DB teach 등록(음성인식_음소템플릿).
  • VM 실측 추가 함정: 클립당 MFCC 파이프라인 ~3.4M 배열유닛 → 배열힙 48M 캡 OOM(14클립째, 이후 "배열 캡 도달"/곱셈 오버플로 경고 연쇄는 전부 corruption 낙진). 해법=클립 단위 메모리마커/복원(730/731)+맵힙마커/복원(734/735), 누산은 맵(하향힙)에 정수만 → 복원과 무관하게 생존.
  • 정직 평가(8클립 홀드아웃): top1 1/8 · 오확정 0/8 · 모름율 8/8. 원인=템플릿 붕괴(전 음절 d0=-1,d1=-1,d3=+1 공통, 이=고=오 완전동일) → 동률시 후보투표 첫순번("하")로 전부 수렴. 오확정 0 = 모름선언 설계는 작동(환각 없음). 13차원 멜에너지 MAD정규화+삼진양자화가 음절 변별력 부족 — 다음 손잡이: 델타(시간차분) 특징 추가, 프레임 3구간(초성/중성/종성부) 분할 템플릿, 임계(200/600) 튜닝, 멜필터 log 정식화.

CIF/CAF 치환 판정 (사용자 질의 — 코덱 실사)

코덱현 상태STT/OCR 치환 판정
CIF(이미지)성숙 — libs/CIF.한선 204/204 테스트, CIF_파일읽기·9트릿RGB·트릿트리 API 완비OCR 입력 1순위 확정. 픽셀=트릿벡터 → [3]삼진양자화 생략, 해독성 원리 그대로 실현
CAF7(오디오)설계=MDCT 벡터형 33t이나 현 구현=PCM+노이즈게이트(caf녹음기 "실제 MDCT 대신" 주석, 파일구조 [20..]=PCM int16)현재 치환 이득 없음(WAV와 동급 PCM). MDCT 벡터형 실장 후 치환 → STT [1][2] 프론트엔드 통째 생략
VM 네이티브 MDCTopcode425/426 존재(코사인테이블 최적화) — 단 aud_handle 입력(배열 직접 불가)중기: WAV→aud_handle 통합으로 DFT 네이티브화, CAF7 인코더 MDCT 실장의 기반

3차 진행 — 4작업 병렬 (2026-07-02 저녁)

  • ④ 게이트웨이 연결 완료: com.crowny.voice LaunchAgent(KeepAlive) 상시기동 + gateway.yaml 라우트(ports.sh 자동) + cert-manager sync(ext2 버킷 38개, voice 포함 발급) + stunnel-live.conf 재생성(131→133 SNI, 탈락 0 확인 후 교체)+SIGHUP 무중단 리로드 → https://voice.crowny.org/health 공개 200. 회귀 0(finance/game/code 200).
  • ①실코퍼스 음절템플릿 학습 / ②CAF7트릿 프로파일 v0 / ③OCR 착수(CIF입력) — 속행집사(sonnet) 3병렬 진행중(가드레일+당일 VM함정 주입).
  • ③OCR 착수 완료(2026-07-03): /Users/ef/crowny-ocr/ — 숫자 0~9 부트스트랩(문자모델삼진.한선)
+ CIF입력.한선(CIF글자셀추출) + OCR디코더.한선(LLM결합 재사용). E2E: 정상셋 3/3, 오확정 0/3, 노이즈셋(30%) O판정 1/1·후보포함진실 1/1. 잔여: CIF 좌표범위(±13, 글리프1개/파일 한정), 대량배치 VM힙 OOM, 한글 확장 미착수. 상세: 2026-07-03-크라우니OCR-1차착수.md.

CAF7 트릿 프로파일 v0 결과 (2026-07-03, 정직 라벨링)

목표: MDCT 정식 실장(opcode425/426, aud_handle 입력 — 본실장은 후속) 전 단계로, "파일에서 트릿 직접 추출" 해독성을 실증. 정직 라벨: "CAF7-STT트릿 프로파일(v0)"이며 CAF7 설계문서의 MDCT 벡터형 정식 실장이 아님을 코드 주석·본 문서에 명기.

  • 신규: /Users/ef/crowny-voice/libs/CAF7트릿.한선 — 포맷 C7T0(매직4B)+샘플레이트(4B LE)+프레임수(2B LE)+계수수(2B LE=13)+프레임데이터(트릿당1B: A=0/O=1/T=2).
  • CAF7트릿인코딩(wav경로,caf경로): WAVMFCC추출(64,32,200)→프레임별 벡터양자화→버퍼기록→버퍼파일쓰기
  • CAF7트릿읽기(caf경로): 파일→헤더검증→프레임별 13트릿 배열 목록 반환
  • 바이트팩킹은 나눗셈 자연반올림 함정 회피용 절단몫/모듈로 헬퍼(CAF7_ 접두, 기존 정모듈로와 이름충돌 회피) 사용. 버퍼바이트/버퍼바이트읽기/버퍼길이/버퍼파일쓰기/버퍼파일읽기 5바이트 왕복 프로브로 시그니처 먼저 실측 검증 후 작성.
  • E2E 검증 (입력: say Yuna "하나" → 16kHz WAV, 200프레임×13계수):
  • 왕복 비트정확: 직접양자화 vs 인코딩→파일→읽기, 2600/2600 트릿 완전 일치
  • 크기: WAV 17,352B vs .c7t 2,612B → 압축비 6.643배
  • 속도 (5회 별도 프로세스 time 실측, VM 핫루프 배열힙 OOM 회피 위해 프로세스 분리):
  • - WAV경유 전체 파이프라인(특징추출+양자화): 5회 13.836s → 평균 2.767s/회 - c7t 직접읽기(특징추출 전체 생략): 5회 0.082s → 평균 0.0164s/회 - → 약 169배 빠름(해독성 이득 정량 증거)
    • 크라우니코드: lookup/search 사전조회 MISS 1건(신규 CAF7 트릿 포맷은 기존 패턴 없음) / 생성 1건 / claude-integration.sh teach "음성인식_CAF7트릿" 학습 등록 완료(LEARNED).
    • VM 함정 재확인: 핫루프에서 WAVMFCC추출을 같은 프로세스 내 10회 반복하면 배열힙 OOM([ARRAY] OOM!)+배열캡(4095) 도달 — 메모리마커/복원 미적용 시 발생. 본 작업은 회피 위해 반복을 프로세스 단위로 분리(향후 실서비스 핫루프엔 메모리마커734/735 적용 필요).
    잔여 이슈:
    1. 이것은 "파일에 미리 계산된 스펙트럼 트릿을 저장→재사용" 캐시 포맷이지 CAF7의 MDCT 벡터형 정식 실장이 아니다. 정식 실장 경로: WAV→aud_handle 통합(opcode425/426 입력 요건) → CAF7 인코더에 MDCT 대체 → 그 다음에야 CAF7 파일 자체가 "인코딩 시점에 트릿 직결" 가능.
    2. 현 v0는 오프라인 사전 인코딩 전제(마이크 실시간 스트리밍엔 부적합 — 인코딩 자체가 여전히 FFT 기반 무거운 경로).
    3. 계수수 13 고정, 프레임 200 상한(설계 표준과 동일) — 더 긴 오디오는 최대프레임 상향 또는 청크 분할 필요.

    CAF7 MDCT 정식 실장 1단계 — aud_handle 통합 조사+실현 (2026-07-03, 속행집사)

    조사 결론: A(기존 경로 존재, 신규 opcode·C수정 불필요) — crownyc.c 프로덕션 파일/바이너리 무수정으로 완결.

    조사 근거 (crownyc.c 실측 행 번호)

    • AUD_HANDLE_BASE=40000, AUD_SLOTS=8, AUD_MAX_SAMPLES=960000 (crownyc.c:2174-2177)
    • PCM→aud_handle 주입 경로 기존재: 녹음시작(431, AUD_REC_START, crownyc.c:10561)이 슬롯을 리셋+lazy alloc, 녹음프레임(432, AUD_REC_FRAME, crownyc.c:10577)이 1샘플씩 append — 둘 다 hanseonc_high.c:1467-1468에 이미 고수준 빌트인으로 노출되어 있었음(신규 opcode 불필요).
    • MDCT_FWD/INV 고수준 노출 기존재: MDCT순변환(425)·MDCT역변환(426) hanseonc_high.c:1460-1461. 단, opcode 400(AUD_INIT 진짜)과 402/403/404/417~423은 hanseonc_high에 전혀 노출 안 됨(발견: 470~479는 실제로는 HDL opcode(HDL_FORCE 등, crownyc.c:11066)로 재배선되어 있는데 hanseonc_high.c:1449-1458은 여전히 "음초기화/음샘플/음재생..."을 470~479에 잘못 매핑해 놓은 죽은/충돌 코드임 — 호출 시 실제로는 HDL 로직이 실행되는 landmine. 이번 작업엔 미사용이라 우회했으나 별도 정리 필요, 원본 미수정).
    • 계수 소비: 메타 통계(총활성/총소멸/N/프레임수/gmax×1e6/원본n, crownyc.c:10380-10391)는 int_to_cube 평문 인코딩이라 메모리읽기(opcode8, 이미 고수준 노출: hanseonc_high.c:1562)로 정상 판독. 단 개별 계수(헤더 큐브의 k+frame+sign 커스텀 12t+9t+1t 패킹)는 판독 불가 — 평문 인코딩이 아니라 메모리읽기로는 뒤섞인 원시 정수만 나옴, 삼진디코딩(opcode720)은 기존에 이미 broken 판정.

    신규 발견 VM 함정 (실측 확인, 2회 프로브로 재현)

    1. 다중 반환값 유실: 변수 x = 함수() 대입은 스택 최상단(마지막 push) 1개만 SETVAR로 소비하고 나머지는 다음 statement 진행 중 소실됨(2-push 빌트인, 예 MDCT순변환의 [주소,개수]). 해법 실증: 같은 부작용없는(읽기전용) 호출을 변수 메타 = 함수() + 위로()로 재호출 — 위로()(OVER, opcode10, hanseonc_high.c:1592)가 표현식 내부에서 두 반환값을 즉시 합산해 안전 캡처(메타=주소+개수, 이후 주소=메타-개수로 역산). 재호출 비용은 네이티브 MDCT라 무시할만함(0.18s대).
    2. aud_sys_init 은폐 데이터손실: 녹음시작/녹음프레임은 aud_sys_init()을 호출하지 않는데, aud_alloc 경유 opcode(음녹음416·MDCT역변환426·음파형424)가 처음 실행될 때 aud_sys_init()aud_data[0..7] 전체를 NULL로 리셋함(crownyc.c:2194-2201). 녹음시작으로 먼저 채운 뒤 MDCT역변환을 부르면 그 내부의 최초 aud_sys_init 호출이 이미 채운 슬롯을 지우고 같은 슬롯번호를 재할당 — "원본과 복원본이 동일 슬롯"이 되어 비교시 오차=0(거짓 완전복원, 실제로 처음엔 이 버그로 오탐 발생·재현·수정함). 해법: PCM 로딩 전 음녹음(경로) 1회로 프라이밍(aud_alloc 강제 실행) 후 그 핸들을 그대로 재사용.
    두 함정 모두 ~/.claude/knowledge(hanseonc_vm/MDCT_FWD_다중반환_및_aud_sys_init_함정)와 학습DB(CAF7MDCT_aud_handle_다중반환캡처)에 등록.

    실장 산출물

    • /Users/ef/crowny-voice/libs/CAF7MDCT.한선(신규, 순수 한선씨, C/바이너리 무수정): CAF7MDCT_PCM적재(WAV경로,프라이밍핸들)→aud_sys_init 프라이밍+정확한 S16LE 직접읽기로 재적재(배열캡 4095 우회 — 버퍼에서 바로 샘플단위 스트림, 중간 배열 미경유), CAF7MDCT_순변환(핸들)→개수/주소/메타/총활성/총소멸/N/프레임수/gmax1e6/원본n 맵, CAF7MDCT_역변환(주소,개수,레이트)→새핸들, CAF7MDCT_핸들비교(핸들A,핸들B,샘플수)→희소읽기(429) 기반 절대오차 합/평균/최대.

    E2E 실측 (입력: 하나.wav 16kHz, 6628샘플)

    • MDCT 파라미터: N=1024(윈도우), 프레임수=7(패딩 포함), 총활성계수=5874, 총소멸=1294(총 7168=7×1024와 일치 — 정합성 검증됨), 소멸율≈18.05% → 평균 계수/프레임 ≈ 839/1024(활성 기준).
    • 왕복 정확도(핸들A vs MDCT_FWD→MDCT_INV 결과 핸들B, 희소읽기 스케일 ×1000/32 기준): 합오차=228535(스케일값), 평균오차=34(스케일값, raw 환산≈1.09/32767), 최대오차=218(스케일값, raw 환산≈6.98/32767) — 매우 우수한 무손실급 재구성 (다만 aud_sys_init 프라이밍 수정 전엔 오차=0 오탐이 있었음을 투명히 기록 — 이번 값은 수정 후 핸들A≠핸들B 확인된 진짜 비교).
    • 속도 (5회 별도 프로세스 실측, /usr/bin/time -p): 네이티브 MDCT(PCM적재+MDCT_FWD 1회) 평균 0.178s vs 기존 DFT 파이프라인(WAVMFCC추출, FFT간단 200프레임×64샘플) 평균 2.71s약 15.2배 빠름. (주의: 두 경로는 프레임 단위가 다름 — MDCT는 N=1024 대형 윈도우 7개, DFT는 64샘플 소형 프레임 200개. "같은 클립을 주파수영역으로 변환하는 전체 파이프라인" 기준 native-vs-interpreted 속도 비교이지, 1:1 프레임 대응 비교가 아님.)
    • 트릿화 후 변별(요청 항목) — 미완/한계 정직 보고: 개별 계수의 (k,frame,sign) 필드는 커스텀 12t+9t+1t 패킹이라 메모리읽기만으로 분리 불가하고, 소멸율이 실오디오에서 18%나 되어 "저장 순서=순차 k" 가정도 안전하지 않음(합성 톤 테스트에선 3.2%였으나 음성엔 훨씬 높음). 즉 MDCT 계수를 삼진양자화.한선처럼 T/O/A 트릿벡터로 재구성해 음절 변별을 보는 실험은 이번 1단계에서 수행하지 않음(헤더 큐브 디코딩용 신규 opcode 또는 C 레벨 "값-포함 계수 배열 직접 dump" 기능이 있어야 신뢰 가능 — 무리한 억지 디코딩으로 거짓 결과를 만들지 않기 위해 보류).

    잔여 이슈

    1. 개별 MDCT 계수값 판독(트릿화용) — 신규 opcode 필요 가능성 높음(예: "MDCT계수읽기(주소,i)→k,frame,sign,진폭" 4반환 또는 평문배열 dump). 2단계 후보.
    2. hanseonc_high.c:1449-1458의 죽은/충돌 오디오 470~479 매핑(HDL과 충돌) — 별도 정리 티켓 필요, 이번 작업 범위 밖(원본 미수정).
    3. 이번 결과는 opcode 425/426의 "sparse skip" 동작이 음성처럼 조용한 구간 많은 신호에서 소멸율이 커진다는 것도 확인 — 압축비 관점에서는 긍정적(더 희소해짐), 트릿 디코딩 난이도엔 부정적.
    4. 크라우니코드: lookup 사전조회(MDCT/aud_handle/녹음시작/메모리읽기) 기존 히트 있었으나 이번 "aud_handle 다중반환 캡처" 패턴은 MISS → 신규 생성 1건, CAF7MDCT_aud_handle_다중반환캡처로 학습 등록 완료.
    #- 4차 4작업 전부 완료·메인검증(2026-07-03): #3 c7t 서버(0.068s·디코드 동일) / #1 top1 87.5%(메인 재현: 7/8, 미→오만 오답) / #2 한글 OCR(메인 재현: 자모4/4·[54616,45208]·노이즈O) / #4 MDCT(메인 재현: 6628샘플·N1024·7프레임·활성5874·왕복 평균오차34/최대218 준무손실). 신규 VM함정 3건(다중반환 유실→위로() 캡처, aud_sys_init 은폐리셋→음녹음 프라이밍, hanseonc 470~479 죽은코드) 메모리 기록.

    5차 진행 — 켜켜공정 도구화 + 순서작업 (2026-07-03)

    • 방법론 명명·도구화: 켜켜공정(시도→실측→함정→학습→재현→쌓기 6박자) — 기록도구 /Users/ef/crowny-tools/켜켜/(켜켜.한선+켜켜.psv, 쌓기/지표/보기). 개선도구 연마(/Users/ef/crowny-tools/연마/) = 누적 함정의 규칙화 린터(R1 맵꺼내==0, R2 %모듈로, R3 포함 불리언).
    • 연마 실적발: "검증된" 한글음절조합.한선 자모분해가 종성≥15에서 %자연반올림으로 깨짐(분해[6,1,-8]) → 음절정모듈로 수정 → 전수 252/252 왕복 통과. WAV읽기 홀수청크 패딩도 동일 수정. 학습DB fn_STT_자모분해 교정.
    • 순서1 v2 서버 배선: libs/클립분류v2.한선(도구에서 추출) + /api/stt/word 라우트. 라이브 검증: 나=T(마진3)·미=O(후보 이,고,미에 진실 포함). 기존 프레임STT·c7t 회귀 정상.
    • 순서2 임계 튜닝: 절대임계 9조합 스윕 — 마진1=오확정1(위반)/마진3=T1/8/마진2·점수3 채택=T4/8·오확정0·O4(전부 top1정답=LLM해소가능). 교훈: 정수 배율 파라미터가 최적점(절대2)을 사각에 놓침 → 절대임계로 전환.
    • 순서3(OCR 40자모+종성) 진행중 → 순서4(MDCT C dump+죽은코드, quadcode 절차) 대기.

    관련 파일 (이번 작업)

    • /Users/ef/crowny-voice/libs/CAF7MDCT.한선 (신규)
    • 프로브 스크립트(임시, 재현용): /private/tmp/claude-501/-Users-ef/38950a42-7c49-4f50-8ade-1d7feb8042ec/scratchpad/mdct/probe1~5.한선, e2e_mdct2.한선, speed_mdct.한선, speed_dft.한선
    • 조사 대상: /Users/ef/CrownyOS/crownyc/crownyc.c(오디오 섹션 10051-10600, HDL 11066-11140), /Users/ef/CrownyOS/crownyc/hanseonc_high.c(1448-1499 오디오 빌트인 테이블)

    4차 진행 — 후속 4작업 (2026-07-03)

    • #3 서버 c7t 직접 입력 완료: 삼진디코더에 트릿디코드()+세그먼트요약열처리() 추가(기존 디코드 무수정), 서버 STT실행이 .c7t 확장자 감지→CAF7트릿읽기→트릿디코드(양자화·특징추출 생략). build.sh에 CAF7트릿 포함, 재빌드+kickstart. 실측: c7t 경로 0.068s(WAV 경로 ~2.7s), 디코드 결과 WAV 경로와 완전 동일(14 모름슬롯 일치). WAV 회귀 정상.
    • #1 변별력 개선(델타·3구간·log멜) / #2 OCR 한글 자모+다글리프 / #4 MDCT aud_handle 조사·실장 — 속행집사 3병렬 진행중.

    #1 음절 변별력 개선 결과 (2026-07-03, 속행집사)

    목표: 3차 학습에서 붕괴한 13차원 멜에너지 MAD정규화 단일템플릿(top1 1/8)을 개선. 손잡이 3개(델타·3구간분할·정식log멜) 조합 절제실험. 기존 함수 무수정 — 전부 신규 파일.

    • 신규 파일: libs/특징추출v2.한선(로그십·멜변환로그·멜필터로그·델타추가·구간분할3·WAVMFCCv2추출), tools/템플릿학습v2.한선(환경변수 VOICE_LOGMEL/VOICE_DELTA/VOICE_SECTIONS로 조합 스위치 + 벡터길이비례 판정임계 음소분류v2), libs/음소템플릿v2.한선(최종 채택모델).
    • 분류기 구조 변경: v1은 프레임별 분류+세그먼트요약(가중다수결)이었으나, v2는 클립 전체를 구간별 부호다수결로 단일 요약벡터화(훈련·테스트 동일 규칙) 후 템플릿과 트릿내적 1회 비교로 top1 결정 — 동률시 후보 첫순번 수렴 버그(v1에서 전부 "하"로 수렴) 회피.
    • 판정임계 길이비례: 13차원 고정임계(마진≥2·점수≥3)를 그대로 안 쓰고 임계 = 원래값 × 벡터길이/13로 재계산(OCR 64차원 선례 반영).

    절제(ablation) 결과 표 — 8클립 홀드아웃(rate=180), 훈련=rate 140+220, 오확정 전 조합 0/8

    조합 (로그멜/델타/구간수)벡터길이top1오확정모름율
    1차(v1, 프레임별+세그먼트요약)131/8 (12.5%)0/88/8
    v2 분류기만 교체 (0/0/1)133/80/87/8
    델타만 (0/1/1)263/80/88/8
    3구간분할만 (0/0/3)395/80/88/8
    델타+3구간 (0/1/3)785/80/88/8
    log멜만 (1/0/1)135/80/87/8
    log멜+델타 (1/1/1)265/80/88/8
    log멜+3구간 (1/0/3) — 채택397/8 (87.5%)0/88/8
    log멜+델타+3구간 (1/1/3)786/80/88/8
    결론(정직): top1 12.5%→87.5%(7/8), 오확정 전 조합 0/8 유지(환각 없음 설계 목표 지속 달성). 최대 기여= 3구간분할(초/중/종성 시간구조가 실제 변별력 원천, 단독으로 3/8→5/8) + 정식 log멜(선형근사 대비 단독 3/8→5/8, 3구간과 결합 시 시너지로 7/8까지 상승). 델타는 이 코퍼스·이 분류기 구조에서 기여 없음/역효과(78차원 조합이 39차원보다 -1/8) — 짧은 음절(0.3~0.5초)이라 인접 프레임 차분이 신호보다 노이즈에 가까운 것으로 추정. 모름율은 전 조합 7~8/8로 v1과 비슷(판정 임계를 넘는 절대마진이 잘 안 나옴) — top1 순위는 크게 개선됐지만 "확신(T)" 판정 자체는 여전히 드묾(정직한 모름 선언 유지, 강제확정 없음).
    • 채택 모델: libs/음소템플릿v2.한선(로그멜=1,델타=0,구간수=3, 39차원). 학습DB teach 등록 완료(음성인식_특징추출v2·음성인식_템플릿학습v2·음성인식_음소템플릿v2, 전부 LEARNED).
    • 잔여 이슈: (1) 모름율이 여전히 높음(판정=1 거의 없음) — 임계 재튜닝 또는 마진 계산식 개선 여지. (2) 8음절 소규모 검증(8클립)뿐 — 확장 코퍼스 필요. (3) 서버(음성인식서버.한선)는 아직 v1 부트스트랩 템플릿(음소템플릿.한선) 사용 중 — v2 전환은 별도 배선 작업(본 작업은 라이브 무접촉, 기존 함수 무수정 원칙 준수).

    관련 파일

    • 프로젝트: /Users/ef/crowny-voice/ (libs/)
    • 기존 자산: 학습DB fn_음성인식_STT생성·멜필터·프레임분할·FFT간단·해밍윈도우
    • 오디오포맷: 메모리 project_crowny_audio(CAF), project_caf7_final
    • 포트: voice.crowny.org:9971
    • CAF7 트릿 v0: /Users/ef/crowny-voice/libs/CAF7트릿.한선

    6차 진행 — MDCT dump opcode + hanseonc 죽은코드 정리 (2026-07-03)

    작업 지시: VM(crownyc.c)에 MDCT 계수 개별필드 추출 opcode 신설 + hanseonc_high.c의 470~479 오디오 죽은매핑(HDL opcode와 충돌) 정리. 원본은 절대 미수정, /tmp 사본에서만 작업 후 unified diff 패치 2개만 산출.

    1. 패치 2개 + diff 규모

    • /Users/ef/crowny-voice/patches/mdct-dump.patch — crownyc.c 대상, 62줄(+32/-0)
    • /Users/ef/crowny-voice/patches/hanseonc-deadcode.patch — hanseonc_high.c 대상, 46줄(+23/-11)
    • 주의: 작업 중 원본 crownyc.c다른 세션에 의해 수차례 실시간 편집되는 것을 md5 변화로 감지(양자 게이트/MPS 24큐비트 확장 등 무관한 작업). 패치는 작업 완료 시점의 원본 스냅샷 기준.
    2. 회귀 결과
    • tests/*.한선 87개 전수, 신구 바이너리 컴파일+실행 출력 diff 비교: 87/87 통과 (0 diff)
    • /Users/ef/crowny-voice/음성인식서버.toau: /tmp/crownyc_v12 run으로 기동 로그(로드: 31334 cubes) 원본과 완전 동일. 포트 9971은 이미 다른 라이브 프로세스가 점유 중이라 바인딩은 실패 로그를 남기지만 이는 VM 정상 동작(포트 충돌은 본 검증과 무관, 건드리지 않음).
    • /Users/ef/crowny-ocr/OCR_한글완성판_E2E.toau: /tmp/crownyc_v12 run vs 원본 crownyc run 출력 71줄 완전 동일.
    3. MDCT 트릿화 E2E 수치 (신규 파일 /Users/ef/crowny-voice/libs/CAF7MDCT트릿.한선)
    • 입력: 하나.wav(16kHz, 가용샘플 6628)
    • VM 보고 총활성 계수: 5874 / opcode881(계수필드)로 실제 추출한 개수: 5874 — 완전 일치
    • 프레임 수: 7
    • 프레임0 히스토그램(13빈): [20,0,0,0,7,68,85,162,205,168,135,46,5] → 트릿벡터 O A A A O O T T T T T O O
    • 프레임1 히스토그램: [0,0,0,0,5,29,59,81,132,178,179,143,126] → 트릿벡터 A A A A O O O T T T T T T
    • DFT 대조 경로(WAVMFCC추출+삼진양자화, 13차원 MFCC): 프레임0 A A O T O O O O O O T T O, 프레임1 A A O T O O O O O O O O A — MDCT/DFT 값 자체는 다르되(설계상 당연) 양쪽 다 트릿벡터 산출 가능함을 실증 → 보류돼 있던 "MDCT 트릿화" 목표 달성.
    • 함정 발견 및 회피: 최초 구현은 (k,frame,sign,value) 4필드를 맵 배열에 누적 후 히스토그램화했는데, 계수 5874개가 배열 캡(4095) 함정에 걸려 배열 자체는 4095개에서 잘리고 "추출개수"만 5874로 정확히 보고되는 은폐된 데이터 손실이 실측됨(프레임0 bin0 값이 2 → 실제 20으로 밝혀짐). 배열 누적을 없애고 opcode를 즉시 히스토그램에 스트리밍 반영하는 구조로 재작성해 해결(WAV읽기.한선의 "배열 캡 회피" 철학과 동일).
    4. 신설 opcode
  • 번호: 881 (이름: 계수필드 / 영문 COEF_FIELD, 881~889 구간 중 최초 채택)
  • 시그니처: 계수필드(계수주소, 인덱스, 필드번호) → 정수값
  • 필드번호 0=k(주파수빈, 12트릿), 1=frame(프레임번호, 9트릿), 2=sign(부호, -1/0/1), 3=value(부호적용 원시 진폭 정수, amp×sign — 물리 스케일 복원엔 meta의 gmax1e6 별도 필요)
  • 단일 push만 수행(다중반환 유실 함정 회피). crownyc.c 4곳(한글명 함수/영문명 함수/asm_lookup 파서/실행 switch) 모두 등록, hanseonc_high.c 빌트인 테이블에도 {"계수필드", 881, 3} 등록.
  • MDCT_FWD(425) 계수쌍 레이아웃 확인: 인덱스큐브(짝수 오프셋) t[0..11]=k, t[12..20]=frame, t[21]=sign / 진폭큐브(인덱스+1) t[0..23]=|amp|(3^24 스케일 절대값).
  • 5. hanseonc_high 470~479 죽은코드 정리

    • 제거(주석 비활성화) 대상 10개: 음초기화·음샘플·음재생·음저장·음톤·음계·음해제·음길이·음레이트·음믹스 (전부 470~479)
    • 원인: crownyc.c에서 470~479는 이미 HDL opcode(HDL_FORCE/HDL_SYSTASK/HDL_INOUT/HDL_CASEX/HDL_DEFPARAM/HDL_GENFOR/SV_CLASS/TC_INST/HKT/TYPE_FAM)로 실장돼 있어, 이 10개 이름을 호출하면 오디오가 아니라 엉뚱한 HDL 로직이 실행되는 지뢰였음(crownyc.c 쪽엔 이미 진짜 AUD_INIT/AUD_SAMPLE/AUD_MIX가 400/419/421에 정상 존재 — 완전 중복+오배선).
    • breaking 확인: 유일한 실사용처 /Users/ef/CrownyOS/crownyc/examples/심화_오디오합성.한선이 이 이름들을 호출함. 원본으로는 컴파일 성공(exit 0, HDL 로직이 조용히 실행되던 상태), 패치 적용본으로는 컴파일 실패(exit 1, "미정의 함수" 에러 6건) — breaking 있음. 완전 제거 대신 "주석 비활성화 + 경고 코멘트"로 처리해 재활성화 필요시 참조 가능하게 남김. crownyc.c 자체의 asm_lookup 함수 내부에도 AUD_INIT/AUD_SAMPLE/AUD_MIX가 400/419/421과 470/471/479로 이중 정의(선행 매치가 항상 이겨 470쪽은 원래도 도달불가 dead code)된 기존 결손을 추가로 발견 — 이번 패치 범위 밖이나 별도 정리 필요성 기록.
    6. 크라우니코드 학습: lookup 1회(MISS: "MDCT계수필드추출") → add 2회 등록("MDCT계수필드opcode", "CAF7MDCT트릿화"). 스크립트 정상 동작 확인.

    7. 잔여 이슈

    • examples/심화_오디오합성.한선은 hanseonc-deadcode.patch 적용 시 컴파일 실패함(breaking, 위 5번 참조) — 패치 적용 시 이 예제도 함께 갱신(신규 오디오 opcode 배선 또는 예제 폐기) 필요.
    • 계수필드(3)=value는 amp×sign 형태 원시 정수이며 물리 스케일 복원에는 meta의 gmax1e6/amp_half 재환산이 필요함(현재 CAF7MDCT트릿.한선은 상대크기 히스토그램 목적이라 원시값을 그대로 사용).
    • crownyc.c의 asm_lookup 내 AUD_INIT/AUD_SAMPLE/AUD_MIX 이중정의(400/419/421 vs 470/471/479, 선행 매치 우선이라 후자는 도달불가)는 이번 패치 범위 밖 — 별도 후속 정리 권장.
    • 모름율(O 판정 비율)이 MDCT/DFT 양쪽 다 높음 — 임계·기준단위 튜닝은 후속 과제.
    • 패치 2개는 메인 세션이 검토 후 별도 판단(승격 여부) — 이번 작업에서는 적용하지 않음.

    7차 진행 — 코퍼스 확장 30음절×5속도 → v3 재학습·재평가 (2026-07-03, 속행집사)

    목표: v2(8음절, log멜+3구간 채택)를 30음절 코퍼스로 확장해 정직 재평가 — 8클래스 대비 하락 그대로 보고.

    • 코퍼스 확장: 기존 8음절(하나이고미수오비, rate 140/180/220)에 신규 22음절(가너도루모버셔애저초케투포휴기냐대래매배새와) × 5속도(120,140,180,220,260) 추가 → 총 30음절×5속도=150 WAV 16kHz mono. say -v Yuna -r <속도> + afconvert -f WAVE -d LEI16@16000 -c 1. 함정 재확인: zsh는 for x in $변수 unquoted 시 bash와 달리 word-split 안 함(파일명에 공백통짜로 뭉침) → 배열=(...) + "${배열[@]}"로 수정 필요(1회 실수·즉시 정정, 잔여 오염 없음 확인).
    • v3 학습 도구: tools/템플릿학습v3_음절.한선(신규) — v2와 동일 채택 조합(로그멜=1,델타=0,구간수=3,D=13→39차원, 델타는 v2 절제실험에서 무기여 확인되어 제외). 30클래스 배열힙 부담 회피 위해 음절 1개당 별도 crownyc run 프로세스로 실행(환경변수 VOICE_SYL/VOICE_OUT), 결과를 PSV(음절|d0,...,d38)로 append, 전량 완료 후 30줄을 조립해 lib 소스 생성. 훈련=속도120/140/220/260(4클립), 테스트=180 홀드아웃(v1/v2와 동일 프로토콜).
    • 산출: /Users/ef/crowny-voice/libs/음소템플릿v3.한선학습된모델생성v3(), 이름들 30종, 기존 부트스트랩모델생성() 구조 그대로(트릿내적() 재사용 가능). 컴파일·로드 검증 통과(이름수=30).

    정직 평가 (30클립 홀드아웃, v2분류(벡터,모델,2,3) 절대임계 그대로 적용)

    지표
    top1 정확도15/30 (50.0%)
    T정답률(판정1&정답)3/30 (10.0%)
    오확정률(판정1&오답)0/30 (0.0%) — 목표 달성, 환각 없음 유지
    모름율(판정0)27/30 (90.0%)
    O클립 후보포함진실률7/27 (25.9%)
    8클래스(v2) 대비 하락 — 정직 보고: top1 87.5%→50.0%, T정답률(구 T4/8=50%)→10.0%, 모름율 8/8(100%)→90.0%, 특히 O해소가능률이 v2에서 전부(순서2 임계튜닝 기록: O4건 전부 top1정답=LLM해소가능, 100%)였는데 30클래스에서는 25.9%로 급락 — 클래스 3.75배 증가(8→30)로 템플릿 붕괴 재발(39차원에서도 "이/고/미", "도" 등 소수 클래스가 다수 음절을 흡수하는 attractor sink 현상).

    혼동 상위 (sink 그룹 기준, 개별 pair는 전부 1회씩·반복쌍 없음, 총 15건 오분류 중):

    • sink=: 기,새,수,투 → 도로 오분류 (4건)
    • sink=: 루,매,모,배 → 미로 오분류 (4건)
    • sink=너: 냐→너 / sink=오: 너→오 / sink=애: 대→애 (각 1건)
    • 예측 분포 자체가 미(5회)·도(5회)에 쏠림(30건 중 10건=33%가 두 sink로 수렴) — 39차원 log멜+3구간 특징이 30클래스 변별에는 부족함을 시사.

    임계 재점검 (마진임계 {1,2,3} 스윕, 점수임계=3 고정, 30클래스)

    마진임계T판정수T정답오확정모름
    113/30103(위반)17
    2(현 채택)3/303027
    30/300030
    결론(정직): 오확정0 제약하 현 채택값(마진임계2/점수임계3) 그대로가 30클래스에서도 최적 — 마진1은 오확정3건 발생(제약 위반), 마진3은 T판정 자체가 0으로 붕괴. 서버 임계값 변경 불필요(제안만, 변경은 메인 위임 원칙대로 미반영). 다만 T판정수 자체가 3/30(10%)로 8클래스 때(4/8=50%)보다 절대적으로 희소해짐 — "정직한 모름 선언" 설계 목표는 유지되나 실사용성(LLM 해소 부담)은 30클래스에서 커짐.

    크라우니코드

    lookup/search 사전조회: 기존 v2 패턴 재사용(클립분류v2.한선·특징추출v2.한선 등 무수정 조립) MISS 0건(전부 기존 함수 조립) / 생성 3건(템플릿학습v3_음절.한선, 평가v3_음절.한선, 임계스윕v3_음절.한선) / crownycode-learn.sh add "음성인식_음소템플릿v3" 학습 등록 완료.

    잔여 이슈

    1. 30클래스 변별력 근본 부족 — 39차원(log멜+3구간)이 8클래스에선 충분했으나 30클래스에선 attractor sink(미/도)로 재붕괴. 다음 손잡이 후보: (a) 더 세밀한 구간분할(5구간 등), (b) 부호다수결 대신 클래스별 통계적 판별(LDA류) 검토, (c) 초성군집 기반 계층적 분류.
    2. O클립 후보포함진실률 25.9%는 LLM 문맥해소 신뢰도가 30클래스에서 낮아짐을 의미 — 후보 3개 고정 대신 동적 K 확대 검토 여지(무리한 튜닝으로 거짓 개선 만들지 않기 위해 이번 범위 밖 보류).
    3. 서버(음성인식서버.한선)는 여전히 v1(음소템플릿.한선) 기반 — v3 전환은 별도 배선 작업(본 작업 라이브 무접촉 원칙 준수, 신규 파일만).
    4. /Users/ef/crowny-voice/patches, /tmp/crownyc_v12*는 타 세션 작업영역이라 접근하지 않음(지시 준수).

    관련 파일 (7차)

    • /Users/ef/crowny-voice/tools/템플릿학습v3_음절.한선 (신규)
    • /Users/ef/crowny-voice/tools/평가v3_음절.한선 (신규)
    • /Users/ef/crowny-voice/tools/임계스윕v3_음절.한선 (신규)
    • /Users/ef/crowny-voice/libs/음소템플릿v3.한선 (신규 — 30음절 v3 모델)
    • 코퍼스: /private/tmp/claude-501/-Users-ef/38950a42-7c49-4f50-8ade-1d7feb8042ec/scratchpad/corpus/(150 WAV)
    • 중간 산출(PSV/로그): .../scratchpad/v3build/(templates.psv, eval.psv, sweep.psv 등)

    8차 진행 — 학습DB 음성인식 패턴 연마 소급 (2026-07-03, Q8)

    목적: fn_음성인식_FFT간단(스펙트럼 전멸)·fn_음성인식_STT생성(==0 가드 무력) 선례처럼, 학습DB에 남아있는 다른 음성인식/오디오 계열 패턴에 동일 계열 실버그가 있는지 소급 점검.

    • 대상: crownycode-learn.sh search "음성인식"/"오디오"로 나온 intent 전량(fn_음성인식_, fn_STT_, fn_한국어처리_자모, fn_한글조합_, 신규 음성인식_(voice 프로젝트 산출물) 등 30여건) — 연마.한선 린터(R1 맵꺼내==0, R2 %모듈로무가드, R3 포함불리언, R4 CL글자수, R5 버퍼읽기오용, R6 정렬무동작) 로직을 텍스트에 직접 적용 + 의심 항목은 실컴파일 실행으로 확정.
    • 정적 린트 결과: 5건 후보(R2 % 플래그) 중 3건은 오탐(정모듈로/음절정모듈로 헬퍼 관련 언급이 주석에 있었을 뿐, 실제 % 연산자 없음 — 음성인식_특징추출·음성인식_한글음절조합·음성인식_WAV읽기는 이미 정상).

    확정 버그 2건 (실측)

    1. fn_음성인식_해밍윈도우 — 원 코드는 계수 = 46 - 46*(i*628/N % 628)/628, 후반부(i*628/N >= 314)는 무조건 계수=54(배율 1.0) 고정. 실측(N=32 프레임, 전원소=1000): index 0~15는 852→444로 잘못된 방향 감쇠(정규 해밍윈도우는 가장자리서 낮고 중앙에서 높아야 함), index 16~31은 전부 1000(테이퍼 전혀 없음). Python 기준값(0.54-0.46cos(2πi/(N-1))×1000) 대비 완전 불일치. 원인: 정수근사 자체가 코사인 곡선이 아니라 선형+반쪽 clamp를 잘못 조합한 것 — 기존에 이미 검증된 코사인() 빌트인(FFT간단에서 실사용 중)을 안 쓰고 임의 근사식을 쓴 것이 근본 원인.
    2. fn_한국어처리_자모분해종성코드=한글코드%28, 중성코드=(한글코드/28)%21를 VM 원시 %(자연반올림, 균형나머지)로 계산 → 종성idx≥15에서 깨짐(전수스캔 28건 중 13건 실패, 예: 종=20 기대인데 결과=-8). 정확히 설계문서에 기록된 "한글음절조합.한선 자모분해 종성≥15 %자연반올림 붕괴" 함정과 동일 계열이나, 다른 intent 이름(fn_한국어처리_자모분해)으로 학습DB에 별도 저장돼 있어 그 수정이 반영되지 않은 채 남아있었음. fn_STT_자모분해(이미 음절정모듈로 사용)는 재검증 결과 0/28 실패로 정상 확인.

    교정

    • 해밍윈도우: 코사인() 빌트인 기반 정식 재작성(계수=540-460*코사인값/1000, 밀리각=6283*i/(N-1)) → N=32 실측 결과 Python 기준값과 ±1~2 오차로 일치(80,90,...,997,997,...,80).
    • 자모분해: 음절정모듈로(절단나눗셈 기반 절단모듈로) 적용판으로 교체 → 종성 0~27 전수 0/28 실패, 초성×중성×종성 84 샘플 전수 0건 실패.
    • 양쪽 학습DB(/Users/ef/CrownyOS/crownyc/data/crownycode/패턴/학습.dat, ~/.crownycode/학습.dat) perl로 구 라인 삭제 후 교정판 append. 수정 전 두 DB 전체를 스크래치패드에 백업. DB 재추출→재컴파일로 저장본 자체가 정상 동작함을 재확인(격리 diff로 내 조작이 딱 4줄(제거2+추가2)만 건드렸음을 별도 검증 — 라이브 학습DB가 타 세션에 의해 동시 편집 중이라 배경 diff 노이즈 있었으나 무관 확인).
    • 참고(미교정): fn_음성인식_주파수를멜로(전 입력에 대해 상수 -2595 반환 — sqrt 오용+스케일 붕괴, 완전 죽은 함수)는 학습DB search 결과엔 안 나왔으나 /Users/ef/CrownyOS/crownyc/libs/음성인식.한선(표준 lib 파일)에 동일 버그로 실존. 이번 작업 범위는 학습DB+/tmp 한정(라이브 lib 파일 무접촉 원칙)이라 DB 교정 대상이 아니었음 — 별도 티켓 권장(정식 log10 대체식은 이미 특징추출v2.한선의 로그십/멜변환로그 기법으로 검증됨, 그대로 이식 가능).

    잔여 이슈

    1. libs/음성인식.한선주파수를멜로() 라이브 버그 — 실사용처는 못 찾음(crowny-voice 프로젝트는 멜필터() 내 인라인 선형근사만 사용, 이 함수 자체는 호출 안 됨)이나 표준 lib API로 노출돼 있어 잠재적 소비자 위험. 후속 세션이 lib 파일 직접 수정 필요.
    2. 서비스 스캐폴드 3종(fn_음성인식엔진_음성인식엔진_*)은 범용 맵 CRUD 패턴 재사용(다른 도메인과 동일 템플릿) — 수치/공식 로직 없어 린트 무해당, 정상.

    크라우니코드

    lookup/search 사전조회 30여건(기존 DB) / 생성 0건(전부 기존 코드 재분석·수정) / 신규 학습 add 없음(기존 intent 이름 유지한 교정 append로 처리, 검증 통과분만 반영).

    9차 진행 — 실시간 스트리밍 STT 1차 (2026-07-04, Q7)

    목표: 오디오 전량 적재 없이 청크 단위로 증분 처리하는 스트리밍 아키텍처 실증. 두 갈래(마이크 경로 조사 + 파일 시뮬레이션 스트리밍) + E2E 배치 대조.

    ① 마이크 경로 조사 결론: 불가(원인 확정, 소스 실측)

    crownyc.c 전체에 CoreAudio/AVFoundation//dev/ 오디오 디바이스 접근이 전혀 없음(grep 0건). 오디오 관련 opcode 재확인:
    • 녹음시작(431)/녹음프레임(432)/녹음정지(436, AUD_REC_START~STOP, crownyc.c:11043-11127) — VM 내부 소프트웨어 샘플 버퍼 API일 뿐(한 샘플씩 push로 채우는 함수 호출 인터페이스), OS 마이크 콜백과 무관.
    • 음녹음(416, "AUD_RECORD", crownyc.c:10614) — 이름과 달리 실제로는 WAV 파일을 fopen으로 읽어 aud_handle에 적재하는 파일 리더(마이크 캡처 아님).
    결론: 헤드리스 셸에서든 어디서든 이 VM에는 실마이크 캡처 경로 자체가 구현돼 있지 않음(권한 문제가 아니라 아예 없음). 실측 실험 없이 소스 확인만으로 원인 확정 — 30분 조사 예산 소진 없이 즉시 ②로 폴백(지시된 정책대로).

    ② 파일 시뮬레이션 스트리밍 — 신규 lib 완성

    /Users/ef/crowny-voice/libs/스트림STT.한선(신규) — 스트림열기(wav경로,모델)/스트림청크(상태,N)/스트림닫기(상태)/스트림실행(경로,N,모델).

    설계 반전 2회 (실측 함정 3건, 정직 기록):

    1. v0: 이월세그를 "프레임분류 맵의 배열"로 상태맵에 보관 + 청크 전체 단위 메모리마커/복원 → 반복 실행 11회째부터 맵꺼내가 전부 -1로 붕괴. 처음엔 배열힙 마커/복원 설계 결함으로 오판했으나, 실제 원인은 BUF_SLOTS=128 고갈(WAV정보()를 청크마다 재호출하면서 버퍼파일읽기 핸들을 해제하지 않음 — 원본 WAV읽기.한선은 배치 1회 호출 전제라 무해제 설계였는데 스트리밍의 "청크당 재오픈" 패턴과 충돌). 버퍼해제(버퍼핸들) 추가로 해소.
    2. 버퍼 해제 후에도 배열힙(48M) OOM이 반복 23회째부터 재현([ARRAY] OOM!) — 원인: "청크 전체 단위" 메모리마커/복원 구조는 세그먼트가 침묵(U)을 못 만나면 절대 회수가 안 걸림. 하나.wav는 파일 끝까지 사실상 활성 세그 1개라 프레임별 임시배열(FFT/멜/트릿벡터)이 실행마다 계속 누적.
    3. v1(채택): 이월세그를 배열로 절대 들고 있지 않고, 모델 이름 개수만큼(≤30) 표_<이름> 스칼라 정수 카운터를 상태맵에 유지 — 프레임마다 분류 후 카운터만 +1, 프레임마다 메모리마커/복원(이월 상태가 전부 스칼라라 항상 안전). 세그 마감 시 표를 스캔(상수 규모)해 세그먼트요약과 동일한 판정식(최고>차점 그리고 과반) 재현.

    E2E 검증 결과 (실측)

    항목스트리밍(20프레임/청크)배치(원시U디코드, 서버 경로 동일)
    확정음소PSV?\|?\|?\|
    신뢰도PSV0,0,0,
    세그수12
    최대/러닝최대에너지6026(최종 수렴)6026(참 최대)
    프레임수206200
    차이 원인(정직 기록): 진짜 최대에너지(6026)는 프레임41에서 처음 등장(실측 확인). 배치는 처음부터 참 최대를 알고 임계(=최대×5%=301)를 고정 적용해 프레임14의 짧은 에너지딥(267)에서 세그를 둘로 쪼갬. 스트리밍은 러닝 최대를 쓰므로 첫 청크(프레임0~19) 동안 러닝최대가 505에 불과해 임계가 25로 훨씬 낮고, 같은 딥이 경계를 못 넘어 세그가 하나로 병합됨. 두 경로 모두 O(모름) 판정을 유지(오확정 0 — "환각 대신 정직한 모름" 설계원칙은 스트리밍에서도 보존), 다만 세그 분할 경계 자체는 러닝최대 알고리즘 특성상 배치와 다를 수 있음이 실증됨.

    메모리 검증

    같은 파일(하나.wav) 100회 연속 스트리밍 실행 — OOM 0, 맵꺼내 오염 0, 전 회차 세그수=1/총프레임수=206으로 완전 일관(v1 수정 후). v0 상태로는 11회째부터 버퍼슬롯 고갈 오염, 23회째부터 배열힙 OOM이었던 것과 대조.

    크라우니코드

    lookup "스트리밍"/"스트림" 사전조회 — MISS(오디오 스트리밍 전용 패턴 없음, JSON스트림/캐릭터모델러 스트림 등은 무관) / 생성 1건(스트림STT.한선) / crownycode-learn.sh add "음성인식_스트림STT" 학습 등록 완료(별칭 "음성인식"에도 연결).

    잔여 이슈

    1. 러닝최대 vs 배치최대 괴리로 인한 초반 세그 경계차는 "정답이 다르다"가 아니라 "스트리밍은 원리상 지연 없이는 완전동일 재현 불가"에 가까움 — 개선하려면 상한을 알고 있는 사전 캘리브레이션(예: 첫 N프레임 프리버퍼 후 최대 추정) 손잡이가 필요(이번 범위 밖, 후속 과제로 기록).
    2. 프레임당 메모리마커/복원 구조는 이 파일(206프레임) 기준 30~100회 반복에서 검증됐으나, 더 긴 오디오(수천 프레임)에서의 배열힙 압력은 별도 스트레스 테스트 필요.
    3. 서버(음성인식서버.한선) 미배선 — 이번 작업은 신규 파일만(라이브 무접촉 원칙), /api/stt/stream 같은 라우트 추가는 별도 배선 작업.
    4. 부트스트랩 모델(이름 4개, ㅏㅣㅎㄴ)만 검증 — v2/v3(최대 30개 이름) 모델과의 조합은 표_<이름> 카운터 방식이 이름 개수에 선형이라 구조상 안전할 것으로 예상되나 실측은 아직.

    관련 파일 (9차)

    • /Users/ef/crowny-voice/libs/스트림STT.한선 (신규)
    • 프로브/테스트 스크립트(임시): /private/tmp/claude-501/-Users-ef/38950a42-7c49-4f50-8ade-1d7feb8042ec/scratchpad/stream/*.한선