Skip to content

Android v1.8 기능 옮기기: 사람 소리, 쉬운 설정, Silero 조기 표시 (v2.1.0) - #7

Merged
amophi merged 8 commits into
mainfrom
feature/mobile-sync
Nov 11, 2026
Merged

amophi merged 8 commits into
mainfrom
feature/mobile-sync

Conversation

@amophi

@amophi amophi commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator

v2.0(10/15) 뒤에 Android에 들어간 것 가운데 PC에도 쓸 수 있는 것을 옮깁니다. 외부 사운드 모드, 진동, 잠금 화면·빠른 설정 타일처럼 Android에만 있는 것은 넣지 않았습니다.

바뀐 것

  • 사람 소리 (Android #421, #426, #447)
    • 재채기·기침·숨소리도 사람 소리로 봅니다. 기본 매핑은 위협음 37, 사람 소리 36, 환경음 448입니다.
    • '대화음' 이름을 '사람 소리'로 바꿨습니다. 18개 언어 가운데 16개는 Android 번역을 그대로 썼고, 중국어 두 개(人声/人聲)는 이미 같은 뜻이라 두었습니다.
    • 분류 탭의 '몸 소리' 묶음은 사람 소리 카드(기침·숨소리·재채기)와 환경음 카드로 나뉩니다. Android와 같습니다.
  • 쉬운 설정 (Android #408/#417, #425, #429, #436)
    • 설정 탭이 '쉬운 설정'과 '자세한 설정'으로 나뉩니다.
    • 쉬운 설정에는 세 칸이 있습니다.
      • 모양: 실제 그리기 엔진으로 그린 카드 4개입니다. Windows 애니메이션 효과가 꺼져 있으면 움직이지 않습니다.
      • 크기: 작게·보통·크게를 선택합니다.
      • 소리 종류: 종류마다 표시를 켜고 끕니다.
    • 자세한 설정에서 맞춘 크기면 세 단계 모두 선택이 풀리고, 그렇다는 안내가 한 줄 나옵니다.
    • '자세한 설정' 버튼은 다른 값을 가진 그 칸으로 바로 갑니다.
    • 처음 설치하면 쉬운 설정으로 엽니다. 이미 쓰던 사람은 네 모드를 건드린 적이 없을 때만 쉬운 설정으로 엽니다.
    • '기본값으로'는 보기 선택을 바꾸지 않습니다.
  • 도움말·튜토리얼 문구
    • 색, 진하기, 민감도, 사운드 모드, 단축키, 성능 항목은 이제 '자세한 설정'에만 있습니다. 이 항목들을 가리키는 문장을 18개 언어 모두 고쳤습니다.
    • Android와 같은 문장은 Android 번역을 가져왔습니다.
  • Silero 조기 표시 (Android #422, #423)
    • 말소리가 처음 잡히면 Silero VAD가 새 소리를 확인합니다. 0.9 이상이 3덩어리 이어지면 '사람 소리'를 한 박자 먼저 화면에 보여 줍니다.
    • 화면과 개발자 HUD에만 씁니다. 정규 결과, 위협음 판단, 분류 탭 지정은 그대로입니다. 분류 탭에 지정이 하나라도 있으면 쓰지 않습니다.
    • 모델은 silero_vad.onnx v6.2.3 (2,327,524 B, SHA-256 1a153a22…88e3)입니다. Android와 같은 파일이고, 불러올 때 해시를 확인합니다. 파일이 없거나 다르면 조기 표시만 꺼집니다.
    • MIT 고지를 THIRD_PARTY.md와 앱 안 라이선스 창에 넣었습니다.
  • 주소 (Android #443)
    • 제보 버튼, '더 알아보기', README 링크를 SOVIS-Team 조직 저장소로 바꿨습니다.
  • 버전: 2.1.0

확인

  • dotnet build -c Release: 경고 0개, 오류 0개
  • 단위 시험 1189개 통과(main은 1000개)
    • 실제 두 모델로 돌린 시험에서, Silero가 있든 없든 정규 결과가 같습니다.
    • 튜토리얼 말소리 파일을 실제 시간처럼 넣으면, 미리보기가 정규 사람 소리보다 120ms 먼저 나옵니다.
    • 정규 리샘플러와 스트림 리샘플러의 출력이 16k~192k의 모든 레이트에서 비트 단위로 같습니다.
  • 쉬운 설정 화면은 창을 띄우지 않고 그린 그림으로 한국어·아랍어·독일어·포르투갈어·힌디어 배치를 봤습니다.

확인하지 못한 것

  • 앱을 실제로 띄워 보지 않았습니다. 클릭, 키보드 이동, 내레이터 읽기, 카드 움직임, 실제 소리에서 조기 표시가 나오는 때와 CPU 사용량이 여기에 해당합니다.
  • 패드 모양 카드는 작은 크기에서 막대가 흐리게 보일 수 있습니다.

Android #421/#426/#447 과 같게 맞춘다. 사람 소리 이름은 18개 언어 중 16개를 Android 번역으로 바꾸고, 중국어 두 곳(人声/人聲)은 이미 같은 뜻이라 그대로 둔다. 분류 탭의 몸 소리 묶음은 사람 소리 카드(기침·숨소리·재채기)와 환경음 카드로 나뉜다.
안드로이드 쉬운 설정(#408, #425, #429)의 규칙을 Core 에 옮긴다. 화면은 다음 커밋에서 더한다.

- 크기 세 단계(EasySizes): 작게 30/40, 보통 = 모드 설정의 처음 값(50/50), 크게 75/70. 안드로이드와 같은 값이다.
  PC 엔진도 크기·진하기를 같은 식으로 쓰고 네 모드 모두 같은 두 값을 쓰므로 모드마다 달리 두지 않는다.
  단계를 쓰면 크기 고정을 끄고 나머지 값은 그대로 둔다.
- 자세한 설정에서 단계와 다르게 맞춘 크기는 어느 단계도 아니다(#425). 화면에 같은 정수로 보이는 값(±0.5)은 같은 단계로 본다.
- '자세한 설정' 칸이 보여 줄 칸(#429): 크기 고정 → 크기 → 진하기 가운데 단계에 맞지 않게 만든 첫 칸.
- AppSettings.EasySettings: 새로 설치하면 쉬운 설정, 항목이 없는 예전 설정 파일은 네 모드가 모두 처음 값일 때만 쉬운 설정이다
  (모바일 loadEasySettings). 정한 값은 다음 저장에 함께 남는다. 화면 설정이라 전체 초기화는 건드리지 않는다.
- 모양 카드 그림: TutorialDemo 가 그릴 설정과 작은 화면(1120×630)을 받는다. PreviewSettings 는 진하기와 반응만 튜토리얼만큼 올리고,
  한 번 움직이는 시간은 4.9초다(WCAG 2.2.2).
안드로이드 #408(#417)과 #425·#429·#436 을 PC 런처에 옮긴다. 설정 탭 맨 위의 두 칸(쉬운 설정 | 자세한 설정)으로
그림으로 선택하는 화면과 지금까지의 모든 설정을 오간다. 새로 설치하면 쉬운 설정으로 연다.

- 모양: 실제 오버레이 엔진으로 그린 카드 넷(ModePreview). 고른 카드만 4.9초 움직인다. Windows 의 애니메이션 효과를 꺼 두었으면
  멈춘 그림이다. 그림은 실제 방향이라 아랍어에서도 뒤집지 않는다.
- 크기: 지금 모드의 세 단계. 자세한 설정에서 맞춘 크기면 선택을 비우고 한 줄로 알린다(#425, 나타날 때 화면 읽어주기가 읽는다).
  밑의 '자세한 설정' 칸은 자세한 설정으로 넘어가 그 모드 카드를 맨 위로 올리고 그 칸(크기 고정·크기·진하기)에 초점을 둔다(#429).
  이 칸은 화살표로 크기를 훑다 넘어가지 않게 선택지 묶음 밖의 단추로 두었다.
- 소리 종류: 위협음 → 대화음 → 환경음 줄에서 화면 표시를 켜고 끈다. 이름은 소리 탭의 종류 이름을 그대로 쓰고, 화면 읽어주기에는
  자세한 설정의 스위치 이름으로 읽힌다. 보이는 종류 이름이 없는 언어는 앞에 붙인다(#436).
- 안드로이드의 진동 줄, 빠른 설정 타일, 외부 사운드 모드 문구는 PC 에 없어 뺐다.
- 새 문구 10개를 18개 언어로 넣었다(안드로이드 easy_* 번역).
색, 진하기, 민감도, 사운드 모드, 단축키, 성능 항목은 이제 설정 탭의 '자세한 설정'에만 있다. Android 와 같은 문장은 Android 번역(#417)을 가져오고, PC 에만 있는 문장(민감도, 성능, 사운드 모드, 단축키)은 같은 표현으로 18개 언어를 고친다.
모바일 #422(PR #423, v1.8.0 부터 기본 켬)의 말소리 미리보기에서 파이프라인에 잇기 전의 부품을 옮긴다.

- SileroInference: Silero VAD v6.2.3(MIT)을 16kHz 512샘플 덩어리마다 돌린다. 파일을 한 번 읽어
  크기 2,327,524바이트와 SHA-256 1a153a22…8788e3(모바일과 같은 값)을 확인한 바이트로 세션을 만든다
  (ModelFileIntegrity.ReadVerified). 순환 상태와 앞 덩어리 끝 64샘플을 이어 받고, YAMNet 처럼 IoBinding 으로
  덩어리마다 할당하지 않는다.
- AiAudioBuffer: 세대(Reset 마다 증가)와 들어온 프레임 수(Cursor), 절대 프레임 범위 복사(CopyRange).
  미래의 소리, 2초 밖으로 밀려난 소리, 이전 캡처의 소리는 읽지 않는다.
- CaptureAudioMath.ResampleStreamBlock: 정규 리샘플러와 같은 계수·같은 연산 순서로 덩어리를 만든다.
  88.2~192kHz 는 정규 경로처럼 늘린 FIR 탭의 범위를 꺼낸다(StreamSourceRange).
- SileroPreviewGate: 새로 들어온 이어진 덩어리 셋이 모두 0.9 이상일 때만, 마감 전에 받아들인다.
- 모델을 앱 빌드·배포 출력의 AIModel 에 넣고, THIRD_PARTY.md(앱의 라이선스 창)에 모바일 NOTICE 와 같은 MIT 전문을 적는다.

시험: 모바일 SileroPreviewGateTest·SileroStreamInputTest 를 옮기고, 모든 PC 레이트에서 정규 리샘플러와
비트까지 같은지, 실제 모델(상태 비우기, 튜토리얼 말소리에서 0.9 이상 셋 이상 연속, 무음에서 0.1 미만, 깨진 파일),
고지 전문을 더했다.
모바일 #422(PR #423)의 화면 전용 말소리 미리보기를 파이프라인과 화면에 잇는다. 기본으로 켠다
(RealtimeAiPipeline.SpeechPreviewEnabled, 모바일 BuildConfig 와 같은 뜻, 사용자 설정은 없다).

- 정규 추론의 프레임이 첫 대화음 후보(기준을 넘은 대화음, 확정은 아직 환경음, 후보 연속 1, 사용자 지정 없음)이면
  그 뒤에 새로 들어온 소리를 배경 스레드 SV-SileroPreview 가 Silero 로 본다. 이어진 덩어리 셋이 모두 0.9 이상이고
  정규 스냅샷 + 250ms 전이면 받아들이고, 화면용 결과(LastDisplayClassification)가 스냅샷 + 275ms 또는 다음 정규
  결과까지 대화음 미리보기를 준다.
- 정규 결과(LastClassification)·위협음·매핑은 바꾸지 않는다. 정규 위협음이나 다음 정규 결과가 늘 이기고,
  사용자 지정이 하나라도 있으면 미리보기를 쓰지 않는다. 멈춤·다시 시작·매핑 변경·닫기에서 미리보기와 후보를 지운다.
- 미리보기 스레드: 캡처 버퍼마다 합쳐지는 깨우기, 한 번에 다섯 덩어리까지, 160ms 넘게 밀리면 버리고 상태를 비운다.
  Silero 를 불러오거나 돌리다 실패하면 미리보기만 꺼진다. Dispose 는 같은 1초 안에서 그 스레드를 기다리고,
  못 기다리면 그 스레드가 끝나며 세션을 닫는다. 미리보기 시각은 Stopwatch 나노초로 잰다.
- 렌더 루프·쉬는 동안의 확인·개발자 HUD 가 화면용 결과를 읽는다. HUD 는 미리보기면 종류 뒤에 " ~PREVIEW" 를
  붙이고, 결과 기록(CSV)에는 모바일처럼 HUD 가 본 결과가 그대로 한 줄로 남는다(열은 그대로).
- 모바일의 HUD 결과 알림(#412)·지연 계측(AiLatencyTrace 등)·비교 APK·진동은 옮기지 않았다.

시험: 모바일 SileroPreviewInstrumentedTest(정규 ONNX 결과 불변, 멈춘 Silero 가 정규 위협음과 닫기를 막지 못함)를
옮기고, 모든 PC 레이트·5.1·7.1 에서 한 틱 먼저 보이기, 만료·마감, 다음 틱 시작, 위협음, 사용자 지정, 멈춤과 다시
시작, 0.9 미만 덩어리, 밀림, 실패, 닫기(모델을 만드는 중 포함)를 더했다. 실제 두 모델에 튜토리얼 말소리를 실시간처럼
넣으면 정규 결과는 미리보기를 끈 파이프라인과 같고, 미리보기가 1380ms 로 정규 대화음(1500ms)보다 120ms 먼저 온다.
제보 버튼과 '더 알아보기'의 GitHub 링크, README 의 내려받기·클론·Android 링크를 SOVIS-Team 조직 저장소로 옮긴다(Android #443 과 같다). 옛 주소는 GitHub 가 넘겨 준다.
@amophi
amophi merged commit bf21c30 into main Nov 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant