-
SoundScape 전체 시스템 구조Project/SoundScape 2025. 2. 21. 22:53
전체 시스템 구조
입력 시스템
- 마이크 입력: 기기의 마이크를 통해 실시간으로 오디오 데이터를 캡처합니다.
- 카메라 입력: ARKit을 통해 기기의 카메라로부터 비디오 프레임과 공간 정보를 캡처합니다.
코어 처리 시스템
- AudioSystem: 오디오 데이터 처리의 핵심 클래스로, AVAudioEngine을 사용하여 마이크 입력을 캡처하고 Accelerate 프레임워크의 vDSP를 활용해 FFT(고속 푸리에 변환)를 수행합니다. 오디오 신호를 12개의 주파수 대역으로 분석하고 FrequencyData 형태로 출력합니다.
- ARSystem: ARKit을 사용하여 AR 세션을 관리하고, 카메라의 위치/방향 정보, 감지된 평면, 주변 조명 정보 등을 ARData 형태로 제공합니다.
- RippleSystem: AudioSystem의 주파수 데이터와 ARSystem의 공간 데이터를 결합하여 각 주파수 대역에 해당하는 시각적 파동(Ripple)을 생성합니다. 생성된 파동 정보는 RippleFrame 형태로 렌더링 시스템에 전달됩니다.
- ARVisualizationViewModel: 전체 시스템을 결합하는 역할을 하며, 모든 하위 시스템(AudioSystem, ARSystem, RippleSystem)을 초기화하고 관리합니다. 또한 에러 처리와 상태 관리를 담당합니다.
렌더링 시스템
- SoundSourceController: AR 공간에서 소리의 시작점을 나타내는 시각적 객체를 관리합니다. 사용자의 제스처를 처리하여 소리 소스의 위치를 변경할 수 있게 하고, 주파수 데이터에 따라 크기, 색상, 회전 등의 시각적 효과를 적용합니다.
- SoundWaveRenderingEngine: RippleSystem에서 생성된 파동 정보를 바탕으로 SceneKit을 통해 실제 3D 파동과 파티클을 렌더링합니다. 각 주파수 대역별로 다른 색상, 크기, 지속 시간을 가진 구형 파동을 생성하고 애니메이션화합니다.
UI 시스템
- ARVisualizationView: SwiftUI를 사용한 메인 뷰로, AR 화면을 표시하고 ARViewContainer를 통해 ARSCNView를 관리합니다.
- OnboardingView: 앱을 처음 사용하는 사용자에게 앱의 기능과 사용 방법을 소개하는 온보딩 화면을 제공합니다.
데이터 흐름
- 입력 데이터 캡처:
- 마이크를 통해 오디오 샘플이 캡처되어 AudioSystem으로 전달됩니다.
- 카메라를 통해 비디오 프레임과 공간 정보가 캡처되어 ARSystem으로 전달됩니다.
- 오디오 처리:
- AudioSystem은 오디오 버퍼를 받아 신호 처리를 수행합니다
- a. Hann 윈도우 함수를 적용하여 신호의 연속성을 확보합니다.
- b. FFT를 계산하여 시간 도메인 신호를 주파수 도메인으로 변환합니다.
- c. Magnitude를 계산하여 각 주파수 성분의 강도를 구합니다.
- d. 로그 스케일 변환을 통해 데시벨 단위로 변환합니다.
- e. 주파수 배열을 생성하고 각 주파수 대역별 에너지를 계산합니다.
- 처리된 데이터는 FrequencyData 객체로 래핑되어 RippleSystem과 SoundSourceController로 전달됩니다.
- AudioSystem은 오디오 버퍼를 받아 신호 처리를 수행합니다
- AR 처리:
- ARSystem은 ARSession을 통해 카메라의 현재 위치/방향, 감지된 평면, 주변 조명 정보 등을 추적합니다.
- 이 정보들은 ARData 객체로 래핑되어 RippleSystem으로 전달됩니다.
- 파동 생성:
- RippleSystem은 FrequencyData와 ARData를 결합하여 각 주파수 대역에 해당하는 파동(Ripple)을 생성합니다.
- 각 파동은 주파수 대역에 따른 고유한 색상, 크기, 복잡도, 지속시간 등의 속성을 가집니다.
- SoundSourceController로부터 사운드 소스의 현재 위치 정보를 받아 파동의 시작점을 결정합니다.
- 생성된 파동 정보는 RippleFrame 객체로 래핑되어 SoundWaveRenderingEngine으로 전달됩니다.
- 시각화 렌더링:
- SoundWaveRenderingEngine은 RippleFrame 데이터를 받아 SceneKit을 통해 3D 파동을 렌더링합니다
- a. 각 주파수 대역별로 SphericalWaveEmitter를 생성하거나 업데이트합니다.
- b. 각 에미터는 구형 메시와 파티클 시스템을 사용하여 파동을 시각화합니다.
- c. 파동은 시간에 따라 확장되고 페이드아웃되는 애니메이션을 적용받습니다.
- SoundSourceController는 FrequencyData를 받아 소리 소스 객체의 시각적 특성을 업데이트합니다
- a. 저주파(베이스) 에너지에 따라 크기를 변경합니다.
- b. 중주파 에너지에 따라 발광 효과를 조정합니다.
- c. 고주파 에너지에 따라 회전 속도를 변경합니다.
- d. 전체 에너지에 따라 표면 변형 효과를 적용합니다.
- SoundWaveRenderingEngine은 RippleFrame 데이터를 받아 SceneKit을 통해 3D 파동을 렌더링합니다
- 사용자 상호작용:
- 사용자가 화면을 통해 제스처(드래그 등)를 입력하면 SoundSourceController가 이를 처리합니다.
- 소리 소스의 위치가 변경되면 이 정보가 RippleSystem으로 전달되어 새로운 위치에서 파동이 생성됩니다.
- UI 업데이트 : ARVisualizationView는 ARSCNView를 통해 AR 장면을 지속적으로 업데이트하여 화면에 표시합니다.
이 모든 데이터 흐름은 Combine 프레임워크를 사용한 반응형 스트림 처리 방식으로 구현되어 있습니다.
각 시스템은 Publisher를 통해 데이터를 발행하고, Subscriber를 통해 다른 시스템의 데이터를 구독하는 방식으로 상호 작용합니다.
이를 통해 비동기적이고 이벤트 기반의 데이터 처리가 가능해지며, 시스템 간의 결합도를 낮추고 모듈성을 높일 수 있습니다.
예를 들어, AudioSystem은 frequencyDataStream Publisher를 통해 주파수 데이터를 발행하고, RippleSystem과 SoundSourceController는 이를 구독하여 각자의 역할에 맞게 처리합니다. 마찬가지로 RippleSystem은 ripplePublisher를 통해 파동 데이터를 발행하고, SoundWaveRenderingEngine이 이를 구독하여 렌더링합니다.
이러한 아키텍처를 통해 Soundscape 앱은 실시간으로 오디오를 분석하고, AR 환경에서 시각적으로 표현하며, 사용자와 상호작용할 수 있는 시스템을 효율적으로 구현하고 있습니다.
'Project > SoundScape' 카테고리의 다른 글
Swift Student Challenge 프로젝트 후기 (0) 2025.02.22