Skip to content

Latest commit

 

History

History
157 lines (111 loc) · 13.4 KB

README.ko.md

File metadata and controls

157 lines (111 loc) · 13.4 KB

English | 한국어


SoundVisualizer

SoundVisualizer 휴대폰에서 본 SoundVisualizer: 환경음, 사람 소리, 위협음, 왼쪽에서 나는 소리, 오른쪽에서 나는 소리

License: Apache 2.0 Android Kotlin Jetpack Compose ONNX

안드로이드용 실시간 오디오 시각화 및 AI 기반 사운드 분석 오버레이


SoundVisualizer는 휴대폰에서 재생되는 오디오를 실시간으로 캡처하여 방향·크기·의미를 그래픽 오버레이와 진동으로 변환하는 안드로이드 애플리케이션입니다. 단순한 파형 시각화를 넘어, YAMNet과 ONNX Runtime 기반의 AI 사운드 분류기를 내장하여 현재 재생 중인 소리의 종류(환경음, 사람 소리, 위협음)를 실시간으로 인지하고 시각·진동 피드백을 제공합니다.


📖 목차


🎯 프로젝트 배경 및 목적

청각장애인의 미디어 접근성 향상

유튜브, OTT, 모바일 게임 등 현대 미디어 콘텐츠의 입체적인 공간 음향 기술은 놀라운 몰입감을 제공하지만, 청각장애인에게는 오히려 심각한 진입 장벽이 됩니다. 기존의 자막 시스템은 단순 대사 전달에 그쳐, 소리의 발생 방향이나 발소리, 총소리 등의 위급한 효과음 정보를 제공하지 못합니다. 본 프로젝트는 손에 든 휴대폰에서 보이지 않는 소리의 방향·크기·의미를 시각화하여 이러한 정보의 불균형을 해소하고 모두가 평등하게 미디어를 즐길 수 있는 환경을 제공하는 것을 최우선 목표로 기획되었습니다.

모두를 위한 활용성 확장

이러한 시각화 오버레이 기술은 비장애인 사용자들에게도 대중교통이나 늦은 밤처럼 소리를 켤 수 없는 상황에서의 해결책으로 작용하거나, 모바일 게이머들에게도 치열한 경쟁 게임 환경에서 추가적인 시각 지표(상황 인지력)를 제공합니다.


✨ 주요 기능

1. 다양한 공간 및 강도 시각화 모드

소리의 크기와 방향(좌우)을 직관적으로 표현하는 4가지 표현 모드를 제공합니다.

  • 파도 모드 (Wave): 화면의 가장자리를 따라 소리의 강도에 비례해 요동치는 파도를 렌더링합니다.
  • 원형 모드 (Circle): 화면 중앙의 고리가 소리가 나는 쪽으로 부풀어 오릅니다.
  • 패드 모드 (Pad): 화면 가장자리 8곳에 고정된 패드 형태로 소리를 표현합니다.
  • 외곽선 모드 (Outline): 파도 모드를 기반으로, 파도의 상한 외곽선 테두리만 표현하여 화면 가림을 최소화합니다.
  • 그래픽은 다른 앱 위에 투명하게 떠 있고 터치는 그대로 아래로 통과합니다. 크기, 진하기, 민감도, 속도, 광원은 모드마다 따로 저장됩니다.
  • 쉬운 설정: 설정 탭에 그림으로 선택하는 화면이 있습니다. 실제 그리기 엔진으로 그린 카드 네 장에서 모양을, 세 단계로 그 모양의 크기를, 소리 종류마다 표시 여부와 진동 세기를 선택합니다. 나머지는 모두 ‘자세한 설정’에 있습니다.

2. 게임을 나가지 않는 실시간 제어

보던 게임이나 영상을 벗어나지 않고도 즉각적인 조작이 가능합니다.

  • 실행 중 알림: 알림에서 바로 시각화를 끄거나 표현 모드를 바꿉니다.
  • 빠른 설정 타일: 앱을 열지 않고 알림창에서 시각화를 켜고 끕니다.

3. 스테레오 방향 인식

  • 휴대폰에서 재생되는 소리의 왼쪽·오른쪽 채널을 비교하여 소리가 나는 쪽과 크기를 표현합니다.
  • 휴대폰 소리는 두 채널이라 좌우는 구분하지만 앞뒤는 구분하지 못합니다. 화면 위·아래쪽 그래픽은 양쪽에서 비슷하게 들리는 소리와 공간감을 나타냅니다.

4. AI 실시간 사운드 분류 (ONNX & YAMNet)

  • 3-Class 분류 체계: 모든 소리를 Ambient(환경음), Speech(사람 소리), Danger(위협음) 3가지로 분석하여 카테고리별로 지정된 UI 색상으로 동적 시각 피드백을 제공합니다. 색상은 커스터마이징이 가능하고, 종류마다 표시를 켜고 끌 수 있습니다.
  • 위협 단서: 사이렌, 경보, 폭발음, 폭죽, 경적, 깨지는 소리 같은 경고음은 모델의 상위 후보 다섯 개 안에(5% 이상) 들기만 해도 위협음으로 봅니다. 음악이나 게임 소리에 묻혀도 놓치지 않기 위해서입니다. 말소리가 더 크게 들릴 때처럼 오경보가 나기 쉬운 몇 가지 경우는 제외합니다.
  • 흔들리지 않는 색: 위협음은 조건을 넘는 첫 결과에 바로 바뀌고, 사람 소리와 환경음은 두 번 연달아 같아야 바뀌어 색이 깜빡이지 않습니다. 조용한 동안에는 AI 가 쉬고, 소리가 나면 바로 다시 듣습니다.
  • 더 빠른 사람 소리: 말소리가 시작되면 작은 음성 감지 모델(Silero VAD)이 새로 들어온 소리를 확인해 사람 소리를 한 박자(약 0.25초) 먼저 보여 줍니다. 화면 표시만 바꾸며, 진동과 위협음 판단, 분류 탭에서 정한 종류는 그대로입니다.
  • 늦게 온 위협음: AI 판정이 나오기 전에 끝나 버리는 짧은 위협음도 그 소리를 나던 때의 크기로 그립니다.

5. 소리마다 종류 정하기 (분류 탭)

  • AI 가 알아듣는 소리 521개를 비슷한 것끼리 묶어 보여 주고, 묶음마다(고급 모드에서는 소리마다) 환경음, 사람 소리, 위협음 가운데 무엇으로 볼지 선택합니다.
  • 이름으로 찾고, 종류나 바꾼 소리로 거르고, 한 번에 모두 되돌릴 수 있습니다. 바꾼 것은 AI 에 바로 반영됩니다.

6. 진동 알림

  • 종류별 진동 방식: 소리 종류마다 꺼짐·느림·중간·빠름·연속 가운데 방식을, 10~100% 로 세기를 정해 촉감만으로도 소리를 구분합니다. 처음에는 위협음만 ‘중간’으로 켜져 있습니다. 쉬운 설정에서는 끔·약하게·세게만 선택합니다.
  • 소리를 따라 울림: 그 종류의 소리가 이어지는 동안 울리고 소리가 멈추면 함께 멈춰, 화면을 보지 않을 때도 소리를 알아챌 수 있습니다.
  • 잠금 화면 알림: 폰이 잠겨 있는 동안 위협음이 들리면 잠금 화면에 알림을 띄웁니다.

7. 외부 사운드 모드

  • 휴대폰에서 재생되는 소리 대신 마이크로 주변 소리를 듣고 같은 그래픽과 진동으로 알려, 화재경보나 사이렌, 누가 부르는 소리를 알아챌 수 있습니다.
  • 들은 소리는 크기를 재고 종류를 구분하는 데만 쓰며, 소리 자체는 파일로 남기거나 밖으로 보내지 않습니다.
  • 마이크 감도는 16단계로 조절하고, 폰이 자기 진동을 소리로 착각하지 않도록 진동하는 동안의 소리는 따로 다룹니다.

8. 도움말, 안내, 튜토리얼

  • 도움말 탭: 시작하기, 권한, 표현 모드, 소리 종류, 자주 묻는 질문, 정보가 미리 채워진 GitHub 이슈나 메일로 보내는 제보 버튼, 오픈소스 라이선스를 담았습니다.
  • 안내: 소리를 받지 못하고 있을 때, 소리 종류 구분을 쓸 수 없을 때, 시각화가 멈춘 까닭을 홈과 실행 중 알림에 알려 줍니다.
  • 튜토리얼: 처음 열면 실제 그리기 엔진과 실제 진동으로 소리, 방향, 소리 종류, 진동이 어떻게 전해지는지 짧게 보여 줍니다. 홈 탭에서 다시 볼 수 있습니다.
  • 개발자 모드: AI 가 들은 소리(상위 다섯 개, 확신도, 걸린 시간)를 오버레이 왼쪽 위에 띄우고, 모든 결과를 앱 폴더의 CSV 파일로 기록할 수 있습니다.

9. 글로벌 다국어 지원

  • 한국어, 영어, 일본어, 중국어(간체·번체), 베트남어, 태국어, 인도네시아어, 스페인어, 포르투갈어(브라질), 프랑스어, 이탈리아어, 독일어, 러시아어, 폴란드어, 터키어, 힌디어, 아랍어(오른쪽에서 왼쪽) 등 18개 언어를 지원합니다. 기본값은 휴대폰 언어를 따르고, 홈 탭의 지구본 버튼에서 바꿀 수 있습니다.

⚙️ 시스템 및 AI 아키텍처

본 프로젝트는 고성능 실시간 처리를 위해 철저한 메모리 관리 및 배터리 최적화로 설계되었습니다.

  • AudioPlaybackCapture: 포그라운드 서비스가 MediaProjection 으로 다른 앱이 재생하는 소리를 캡처하고, 외부 사운드 모드에서는 AudioRecord 로 마이크 소리를 받습니다.
  • 네이티브 채널 크기 측정: 버퍼마다 좌우 채널의 최고 크기를 C++(NDK)로 재어 렌더러에 넘깁니다.
  • Zero-Allocation 렌더링: Jetpack Compose 캔버스 렌더러가 프레임마다 메모리를 새로 잡지 않아 GC 로 인한 프레임 드랍을 막습니다.
  • 프레임과 무관한 움직임, 쉬는 오버레이: 스무딩은 60 FPS 기준으로 맞추고, 120Hz 화면에서도 초당 60프레임(그래픽 덜 자주 그리기를 켜면 30프레임)으로 제한합니다. 보이는 것이 없으면 그리지 않고 쉬다가 소리가 나면 바로 깨어나며, 기본 설정에서는 화면이 꺼지면 쉽니다.
  • ONNX 추론 파이프라인: 250ms 마다 최근 0.975초의 소리를 모노로 섞고, 앨리어싱 방지 필터를 거쳐 16kHz 로 바꾼 뒤, 모델이 만들어질 때와 같은 방식의 Log-mel 스펙트로그램으로 바꿔 ONNX Runtime 의 YAMNet 으로 분류합니다. 모델 파일은 불러올 때 정해 둔 크기와 SHA-256 으로 확인하고, 각 단계는 기준 출력과 비교하는 단위 테스트로 검증합니다.

🚀 설치 및 실행 방법

SoundVisualizer는 Android 10 이상에서 돌아가는 오픈소스 APK 로 제공됩니다.

  1. GitHub Releases 페이지에 접속합니다.
  2. 최신 버전의 SoundVisualizer-vX.Y.Z.apk 파일을 휴대폰으로 다운로드해 엽니다. 알 수 없는 앱 설치를 허용하는지 물으면 허용한 뒤 설치합니다.
  3. 앱을 엽니다. 튜토리얼이 먼저 뜨고, 홈 탭에서 다시 볼 수 있습니다.
  4. 홈에서 실행을 누르고 권한을 허용하면 오버레이가 켜집니다. 다른 앱 위에 표시, 오디오 녹음, 화면 녹화·전송 권한이 필요하며, 화면 녹화·전송은 안드로이드가 휴대폰 안의 소리를 이 방법으로만 넘겨주기 때문에 쓰고 화면 자체는 캡처하지 않습니다.

소리는 휴대폰 안에서만 처리하고, 파일로 남기거나 밖으로 보내지 않습니다.


🛠 빌드 가이드 (개발자용)

코드 수정 및 기여를 위해 소스에서 직접 빌드하는 방법입니다.

  1. 요구 사항: 최신 Android Studio, JDK 17, Android SDK(compileSdk 37). NDK 와 CMake 는 빌드할 때 맞는 버전을 받습니다.
  2. 리포지토리 클론:
    git clone https://github.com/SOVIS-Team/SoundVisualizer-Android.git
  3. 리포지토리 폴더에서 빌드하고 테스트합니다.
    ./gradlew assembleDebug
    ./gradlew testDebugUnitTest
    또는 Android Studio 에서 프로젝트를 열어 빌드하고, 휴대폰이나 에뮬레이터에서 실행합니다.

앱 모듈에는 캡처 서비스(AudioCaptureService), 네이티브 크기 측정(cpp/native-lib.cpp), AI 파이프라인(ai/), 오버레이 렌더러(VisualizerEngine), 진동 알림(feedback/)이 들어 있습니다. 기여 방법은 CONTRIBUTING.md, 데이터 흐름과 스레드 구성은 아키텍처 문서를 확인하세요.


📄 라이선스

이 프로젝트는 Apache License 2.0 하에 배포됩니다. 누구나 코드를 사용하고 수정하여 공유할 수 있습니다. 자세한 내용은 LICENSE 파일을 확인하세요.

분류 탭의 소리 묶음과 소리 이름은 AudioSet 온톨로지를 바탕으로 만든 각색물이라 CC BY-SA 4.0 으로 배포합니다. 사용된 서드파티 라이브러리(ONNX Runtime, AndroidX 등)와 AI 모델에 대한 저작권 및 라이선스 정보는 NOTICE에서 확인하실 수 있습니다.


Built for Accessibility.