← Docs hub

SoundFlow 음성 연속성 패치 실기기 검증

결론: A1 실기기에서 원본 sndflow.ko의 정확한 64샘플, 4 ms zero-fill을 2건 재현했다. 두 사건은 8~16 ms 뒤 원본 64샘플 skip도 동반했다. 공통 cur_jiffies 패치 후에는 더 긴 63.042 stream-min 동안 64-zero와 phase jump가 모두 0건이었다. Queue overflow도 실기기에서 확인됐으며, pop_front() 패치는 한 사건의 손실 상한을 약 320 ms에서 약 64 ms로 줄였다. 다만 overflow의 근본 처리 지연과 KWS/STT 회귀는 별도 과제다.

SoundFlow 음성 연속성 패치 실기기 검증

1. 검증 환경

항목
기기 QTI lahaina A1, Android 13 userdebug
Build A1_BUILD3_732
Kernel 5.4.274-qgki-consolidate, aarch64, PREEMPT
Kernel tick CONFIG_HZ=250, 1 tick = 4 ms
Kardome 1.1.17
시험 신호 16 kHz, PCM16, mono, 모든 샘플 non-zero
ALSA 조건 playback period 512 / capture period 640
추가 부하 원본·패치 각각 ADB read 약 192 MB

설치 전에 원본 서비스, 모듈, Kardome library를 pull하고 SHA-256을 기록했다. 모듈 vermagic와 기기 커널도 일치했다.

파일 원본 SHA-256 앞 8자리 패치 SHA-256 앞 8자리
SoundFlow service 0a50e417 409e10ff
sndflow.ko a2216c74 3e5b9b9e
libKardome.so 8f19cb7d 동일

서비스와 .ko는 파일 교체만 하지 않고 매 조건마다 재부팅하여 실제 로드된 상태를 확인했다.

2. 재현 방법

SoundFlow ALSA loopback의 독립 substream에 규칙적인 non-zero 신호를 재생하고 반대편을 동시에 녹음했다.

sample = 2000 + ((sample_index × 37) mod 12001)

정상 신호에는 0이 없고 다음 샘플도 정확히 계산할 수 있다. 따라서 다음을 동시에 판정할 수 있다.

분석 결과는 재현 가능한 Python 분석기와 metrics.csv로 남겼다.

3. 원본에서 재현된 4 ms 손상

원본 장시간 회차의 유효 direct loopback 노출은 59.987 stream-min이었다.

증거 zero 구간 zero 길이 후속 source skip
stream 7 49.952~49.956초 64샘플, 4 ms zero 종료 8 ms 뒤 64샘플
stream 4 349.984~349.988초 64샘플, 4 ms zero 종료 16 ms 뒤 64샘플

stream 4의 zero 경계는 다음과 같다.

직전: ... 12996, 13033, 13070
문제: 0 × 64 samples
직후: 13107, 13144, 13181 ...

zero 직후에는 13070의 정상 다음 값인 13107이 이어진다. 그러나 뒤쪽 buffer 경계에서는 정상 1-step 대신 65-step 전진하여 정확히 원본 64샘플을 건너뛴다.

4 ms zero-fill
  -> 8~16 ms 동안 일시적으로 정상 연속
  -> buffer 경계에서 4 ms source skip

이 결과는 CONFIG_HZ=250의 한 tick인 4 ms와 WAV 손상 크기가 일치한다는 기존 원인 후보를 실기기에서 직접 뒷받침한다.

4. 패치 후 A/B 결과

사용자의 종료 요청까지 패치 후 7개 direct pair를 각각 541.44초 녹음했다. 마지막 100 ms는 14개 tinycap/tinyplay를 동시에 SIGINT로 닫은 종료 경계로 별도 분류했다.

지표 원본 패치
유효 direct loopback 59.987 stream-min 63.042 stream-min
64샘플 zero 2건 0건
64샘플 source skip 2건, 합계 128샘플 0건
정상 운용 continuity failure 2 stream 0 stream
강제 종료 경계 전이 0건 4건

패치 파일의 종료 전이는 마지막 40~76 ms에만 몰려 있었다. 정상 운용 구간에는 64-zero, phase jump, source skip이 없었다.

이 검증은 공통 cur_jiffies 패치의 실기기 근거다. 다만 유한 시간 시험이므로 모든 운용 조건에서 발생 확률이 수학적으로 0이라고 증명한 것은 아니다.

5. Queue overflow 실기기 결과

패치 서비스 부팅 후 자연 운용 중 다음 로그가 발생했다.

07-30 12:00:45.321 W SoundFlowInput:
threadLoop : input overflow, dropped oldest buffer (dropped=1, queued=4)

입력과 처리 thread 시작 약 9초 뒤의 실제 overflow다.

정책 동작 사건당 최대 손실
원본 5개 queue 전체 clear() 약 320 ms
패치 oldest 1개 pop_front() 약 64 ms

한 buffer는 1,024 frames이며 16 kHz에서 64 ms다. 로그의 queued=4는 oldest 하나를 버리고 최신 네 개를 유지한 구현과 일치한다.

중요한 해석:

6. KWS/STT 영향과 한계

7. 최종 기기 상태

기기는 패치 상태로 유지했다.

init.svc.soundflowservice = running
sys.audio.sndflow.krdm.version = 1.1.17
service SHA-256 = 409e10ffa77925c504f4aea21eaf84f95496aabd929d20604a1b345be3c23f56
sndflow.ko SHA-256 = 3e5b9b9e24ac25011841331e944203de0e8b181a2b7ff5063d2665717abbeeb1
libKardome.so SHA-256 = 8f19cb7d96e858a5a23d01353a07dea54ce6d26323f619af67c0934771e32afe

최종 패치 시험 logcat:

8. 다음 Gate

  1. AFE, KWS, pcm_write(), dump I/O의 buffer별 처리시간과 sequence를 기록한다.
  2. 정상 운용 30분 이상에서 overflow 누계와 서비스 RSS/PSS를 확인한다.
  3. 동일 발화 paired capture로 KWS FRR/FAR와 STT CER/WER를 비교한다.

기존 원인 분석과 코드 경계는 SoundFlow 음성 손상·Zigging 원인 분석을 참조한다.

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date