크라우니음성인식도구 (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 구분자 — 음절/단어 경계
구분점(차별점) 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])만 이미지용으로 교체.
잔여 이슈 / 다음 단계
- P0 계량화 먼저: 음향모델 정확도·모름율·LLM해소 성공률을 실측(스텁 방지 — 메모리 토르 교훈).
- 삼진양자화 임계(θ_low/θ_hi) 튜닝 = 모름율 제어 손잡이. 너무 높으면 전부 O(LLM부담), 너무 낮으면 강제확정(오류).
- 음향모델 학습데이터 = 한국어 음소 코퍼스 필요. 초기엔 규칙기반 포먼트 매칭으로 부트스트랩.
- 크라우니LLM API 계약 확정(모름슬롯 포맷).
- 실시간(스트리밍) 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 네이티브 MDCT | opcode425/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 부트스트랩(문자모델삼진.한선)
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트릿 배열 목록 반환time 실측, VM 핫루프 배열힙 OOM 회피 위해 프로세스 분리):- 크라우니코드: lookup/search 사전조회 MISS 1건(신규 CAF7 트릿 포맷은 기존 패턴 없음) / 생성 1건 /
claude-integration.sh teach "음성인식_CAF7트릿"학습 등록 완료(LEARNED). - VM 함정 재확인: 핫루프에서 WAVMFCC추출을 같은 프로세스 내 10회 반복하면 배열힙 OOM(
[ARRAY] OOM!)+배열캡(4095) 도달 — 메모리마커/복원 미적용 시 발생. 본 작업은 회피 위해 반복을 프로세스 단위로 분리(향후 실서비스 핫루프엔 메모리마커734/735 적용 필요).
- 이것은 "파일에 미리 계산된 스펙트럼 트릿을 저장→재사용" 캐시 포맷이지 CAF7의 MDCT 벡터형 정식 실장이 아니다. 정식 실장 경로: WAV→aud_handle 통합(opcode425/426 입력 요건) → CAF7 인코더에 MDCT 대체 → 그 다음에야 CAF7 파일 자체가 "인코딩 시점에 트릿 직결" 가능.
- 현 v0는 오프라인 사전 인코딩 전제(마이크 실시간 스트리밍엔 부적합 — 인코딩 자체가 여전히 FFT 기반 무거운 경로).
- 계수수 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회 프로브로 재현)
- 다중 반환값 유실:
변수 x = 함수()대입은 스택 최상단(마지막 push) 1개만 SETVAR로 소비하고 나머지는 다음 statement 진행 중 소실됨(2-push 빌트인, 예 MDCT순변환의 [주소,개수]). 해법 실증: 같은 부작용없는(읽기전용) 호출을변수 메타 = 함수() + 위로()로 재호출 — 위로()(OVER, opcode10, hanseonc_high.c:1592)가 표현식 내부에서 두 반환값을 즉시 합산해 안전 캡처(메타=주소+개수, 이후 주소=메타-개수로 역산). 재호출 비용은 네이티브 MDCT라 무시할만함(0.18s대). - 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" 기능이 있어야 신뢰 가능 — 무리한 억지 디코딩으로 거짓 결과를 만들지 않기 위해 보류).
잔여 이슈
- 개별 MDCT 계수값 판독(트릿화용) — 신규 opcode 필요 가능성 높음(예: "MDCT계수읽기(주소,i)→k,frame,sign,진폭" 4반환 또는 평문배열 dump). 2단계 후보.
- hanseonc_high.c:1449-1458의 죽은/충돌 오디오 470~479 매핑(HDL과 충돌) — 별도 정리 티켓 필요, 이번 작업 범위 밖(원본 미수정).
- 이번 결과는 opcode 425/426의 "sparse skip" 동작이 음성처럼 조용한 구간 많은 신호에서 소멸율이 커진다는 것도 확인 — 압축비 관점에서는 긍정적(더 희소해짐), 트릿 디코딩 난이도엔 부정적.
- 크라우니코드: lookup 사전조회(MDCT/aud_handle/녹음시작/메모리읽기) 기존 히트 있었으나 이번 "aud_handle 다중반환 캡처" 패턴은 MISS → 신규 생성 1건,
CAF7MDCT_aud_handle_다중반환캡처로 학습 등록 완료.
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, 프레임별+세그먼트요약) | 13 | 1/8 (12.5%) | 0/8 | 8/8 |
| v2 분류기만 교체 (0/0/1) | 13 | 3/8 | 0/8 | 7/8 |
| 델타만 (0/1/1) | 26 | 3/8 | 0/8 | 8/8 |
| 3구간분할만 (0/0/3) | 39 | 5/8 | 0/8 | 8/8 |
| 델타+3구간 (0/1/3) | 78 | 5/8 | 0/8 | 8/8 |
| log멜만 (1/0/1) | 13 | 5/8 | 0/8 | 7/8 |
| log멜+델타 (1/1/1) | 26 | 5/8 | 0/8 | 8/8 |
| log멜+3구간 (1/0/3) — 채택 | 39 | 7/8 (87.5%) | 0/8 | 8/8 |
| log멜+델타+3구간 (1/1/3) | 78 | 6/8 | 0/8 | 8/8 |
- 채택 모델:
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큐비트 확장 등 무관한 작업). 패치는 작업 완료 시점의 원본 스냅샷 기준.
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 runvs 원본crownyc run출력 71줄 완전 동일.
/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): 프레임0A A O T O O O O O O T T O, 프레임1A 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읽기.한선의 "배열 캡 회피" 철학과 동일).
계수필드 / 영문 COEF_FIELD, 881~889 구간 중 최초 채택)계수필드(계수주소, 인덱스, 필드번호) → 정수값{"계수필드", 881, 3} 등록.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)된 기존 결손을 추가로 발견 — 이번 패치 범위 밖이나 별도 정리 필요성 기록.
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%) |
혼동 상위 (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정답 | 오확정 | 모름 |
|---|---|---|---|---|
| 1 | 13/30 | 10 | 3(위반) | 17 |
| 2(현 채택) | 3/30 | 3 | 0 | 27 |
| 3 | 0/30 | 0 | 0 | 30 |
크라우니코드
lookup/search 사전조회: 기존 v2 패턴 재사용(클립분류v2.한선·특징추출v2.한선 등 무수정 조립) MISS 0건(전부 기존 함수 조립) / 생성 3건(템플릿학습v3_음절.한선, 평가v3_음절.한선, 임계스윕v3_음절.한선) /crownycode-learn.sh add "음성인식_음소템플릿v3" 학습 등록 완료.잔여 이슈
- 30클래스 변별력 근본 부족 — 39차원(log멜+3구간)이 8클래스에선 충분했으나 30클래스에선 attractor sink(미/도)로 재붕괴. 다음 손잡이 후보: (a) 더 세밀한 구간분할(5구간 등), (b) 부호다수결 대신 클래스별 통계적 판별(LDA류) 검토, (c) 초성군집 기반 계층적 분류.
- O클립 후보포함진실률 25.9%는 LLM 문맥해소 신뢰도가 30클래스에서 낮아짐을 의미 — 후보 3개 고정 대신 동적 K 확대 검토 여지(무리한 튜닝으로 거짓 개선 만들지 않기 위해 이번 범위 밖 보류).
- 서버(
음성인식서버.한선)는 여전히 v1(음소템플릿.한선) 기반 — v3 전환은 별도 배선 작업(본 작업 라이브 무접촉 원칙 준수, 신규 파일만). /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건 (실측)
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간단에서 실사용 중)을 안 쓰고 임의 근사식을 쓴 것이 근본 원인.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.한선의 로그십/멜변환로그 기법으로 검증됨, 그대로 이식 가능).
잔여 이슈
libs/음성인식.한선의주파수를멜로()라이브 버그 — 실사용처는 못 찾음(crowny-voice 프로젝트는멜필터()내 인라인 선형근사만 사용, 이 함수 자체는 호출 안 됨)이나 표준 lib API로 노출돼 있어 잠재적 소비자 위험. 후속 세션이 lib 파일 직접 수정 필요.- 서비스 스캐폴드 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에 적재하는 파일 리더(마이크 캡처 아님).
② 파일 시뮬레이션 스트리밍 — 신규 lib 완성
/Users/ef/crowny-voice/libs/스트림STT.한선(신규) — 스트림열기(wav경로,모델)/스트림청크(상태,N)/스트림닫기(상태)/스트림실행(경로,N,모델).설계 반전 2회 (실측 함정 3건, 정직 기록):
- v0: 이월세그를 "프레임분류 맵의 배열"로 상태맵에 보관 + 청크 전체 단위 메모리마커/복원 → 반복 실행 11회째부터
맵꺼내가 전부 -1로 붕괴. 처음엔 배열힙 마커/복원 설계 결함으로 오판했으나, 실제 원인은 BUF_SLOTS=128 고갈(WAV정보()를 청크마다 재호출하면서버퍼파일읽기핸들을 해제하지 않음 — 원본 WAV읽기.한선은 배치 1회 호출 전제라 무해제 설계였는데 스트리밍의 "청크당 재오픈" 패턴과 충돌).버퍼해제(버퍼핸들)추가로 해소. - 버퍼 해제 후에도 배열힙(48M) OOM이 반복 23회째부터 재현(
[ARRAY] OOM!) — 원인: "청크 전체 단위" 메모리마커/복원 구조는 세그먼트가 침묵(U)을 못 만나면 절대 회수가 안 걸림. 하나.wav는 파일 끝까지 사실상 활성 세그 1개라 프레임별 임시배열(FFT/멜/트릿벡터)이 실행마다 계속 누적. - v1(채택): 이월세그를 배열로 절대 들고 있지 않고, 모델 이름 개수만큼(≤30)
표_<이름>스칼라 정수 카운터를 상태맵에 유지 — 프레임마다 분류 후 카운터만 +1, 프레임마다 메모리마커/복원(이월 상태가 전부 스칼라라 항상 안전). 세그 마감 시 표를 스캔(상수 규모)해 세그먼트요약과 동일한 판정식(최고>차점 그리고 과반) 재현.
E2E 검증 결과 (실측)
| 항목 | 스트리밍(20프레임/청크) | 배치(원시U디코드, 서버 경로 동일) |
|---|---|---|
| 확정음소PSV | ?\| | ?\|?\| |
| 신뢰도PSV | 0, | 0,0, |
| 세그수 | 1 | 2 |
| 최대/러닝최대에너지 | 6026(최종 수렴) | 6026(참 최대) |
| 프레임수 | 206 | 200 |
메모리 검증
같은 파일(하나.wav) 100회 연속 스트리밍 실행 — OOM 0, 맵꺼내 오염 0, 전 회차 세그수=1/총프레임수=206으로 완전 일관(v1 수정 후). v0 상태로는 11회째부터 버퍼슬롯 고갈 오염, 23회째부터 배열힙 OOM이었던 것과 대조.크라우니코드
lookup "스트리밍"/"스트림" 사전조회 — MISS(오디오 스트리밍 전용 패턴 없음, JSON스트림/캐릭터모델러 스트림 등은 무관) / 생성 1건(스트림STT.한선) /crownycode-learn.sh add "음성인식_스트림STT" 학습 등록 완료(별칭 "음성인식"에도 연결).잔여 이슈
- 러닝최대 vs 배치최대 괴리로 인한 초반 세그 경계차는 "정답이 다르다"가 아니라 "스트리밍은 원리상 지연 없이는 완전동일 재현 불가"에 가까움 — 개선하려면 상한을 알고 있는 사전 캘리브레이션(예: 첫 N프레임 프리버퍼 후 최대 추정) 손잡이가 필요(이번 범위 밖, 후속 과제로 기록).
- 프레임당 메모리마커/복원 구조는 이 파일(206프레임) 기준 30~100회 반복에서 검증됐으나, 더 긴 오디오(수천 프레임)에서의 배열힙 압력은 별도 스트레스 테스트 필요.
- 서버(
음성인식서버.한선) 미배선 — 이번 작업은 신규 파일만(라이브 무접촉 원칙),/api/stt/stream같은 라우트 추가는 별도 배선 작업. - 부트스트랩 모델(이름 4개, ㅏㅣㅎㄴ)만 검증 — v2/v3(최대 30개 이름) 모델과의 조합은
표_<이름>카운터 방식이 이름 개수에 선형이라 구조상 안전할 것으로 예상되나 실측은 아직.
관련 파일 (9차)
/Users/ef/crowny-voice/libs/스트림STT.한선(신규)- 프로브/테스트 스크립트(임시):
/private/tmp/claude-501/-Users-ef/38950a42-7c49-4f50-8ade-1d7feb8042ec/scratchpad/stream/*.한선