Swift Student Challenge 프로젝트 후기
공간과 감각
혼자 작업할 때 허전한 기분이 들면 그 순간을 채워줄 BGM을 찾습니다.
유튜브를 살펴보면 다양한 플레이리스트들이 있는데,
특히 "카페에서", "해변에서", "공원에서"처럼 특정 장소를 키워드로 선정된 노래들을 들으면
마치 그 장소에 와 있는 듯한 느낌이 들곤 합니다.
눈으로 보는 것이 많은 것들을 확정 짓지만, 느낌은 귀와 더 긴밀하게 연결되어 있는 듯합니다.
"분위기라는 단어가 주는 미묘한 느낌을 시각적으로 표현하면 어떨까?"라는 생각을 가지고 있었고,
Swift Student Challenge에 참가하며 이 아이디어를 앱으로 구현해 보기로 했습니다.
Sound + landscape
프로젝트 이름은 Sound(소리)와 landscape(풍경)를 결합한 'Soundscape'로, '소리가 그리는 풍경'이라는 의미를 담고 있습니다.
소리로 공간의 분위기를 표현한다는 컨셉은 명확했지만, 이를 어떻게 구현할지에 대한 구체적인 방향을 잡기 어려웠습니다.
'Sound visualization' 같은 키워드를 검색했으나, 단순히 음파의 형태를 보여주거나 지나치게 추상적인 시각 예술 작품만 접할 수 있었습니다. 더 직관적이고 몰입감 있는 표현 방식을 원했지만 명확한 아이디어가 떠오르지 않았습니다.
고민 끝에 먼저 실제로 활용 가능한 기술을 탐색하기로 했습니다. Apple에서 제공하는 다양한 프레임워크를 조사하던 중 Accelerate와 ARKit을 발견했습니다.
Accelerate를 통해 저수준의 오디오 처리가 가능했고, 이를 활용하면 푸리에 변환을 통한 소리의 특징을 추출할 수 있었습니다. 또한 ARKit을 사용하면 카메라로 입력되는 실시간 공간 정보 위에 별도로 렌더링 한 객체를 다양한 방식으로 배치하고 결합할 수 있었습니다.
이 두 기술을 핵심으로 활용하여 실시간으로 소리를 입력받아 현재 공간에 시각적 효과를 결합하는 방향으로 프로젝트를 진행하기로 결정했습니다.
프로젝트 설계
프로젝트의 전체 구조를 설계할 때 Input 부분, 데이터 처리 부분, UI 부분으로 분리하기로 결정했습니다. 이는 구체적인 데이터 처리 방식과 시각적 표현 방법이 아직 확정되지 않은 상황에서, 기능별 분리를 통해 의존성을 최소화하고 향후 변경 사항을 쉽게 적용하기 위함이었습니다.
최근에는 초기부터 복잡한 아키텍처를 도입하기보다, 프로젝트 구조를 단순하게 시작하여 필요에 따라 점진적으로 발전시키는 방식이 초기 복잡성을 줄이고 프로젝트의 유연성을 확보하는 더 낫지 않을까라는 생각을 가지고 있어서
처음에는 ViewModel 없이 기능 요소들을 직접 화면단에서 조합하려 했으나, 오디오와 영상 같은 반응형 스트림을 다루면서 Combine 프레임워크가 필요해졌고, 소리 분석 결과를 바탕으로 렌더링된 객체들을 AR 화면에 통합하는 과정에서 여러 스트림을 결합하는 지점이 필요해져, 결국 가장 익숙한 ViewModel을 도입하여 최종적으로 화면까지의 데이터 흐름을 완성했습니다.
SoundScape 전체 시스템 구조
전체 시스템 구조 입력 시스템 마이크 입력: 기기의 마이크를 통해 실시간으로 오디오 데이터를 캡처합니다.카메라 입력: ARKit을 통해 기기의 카메라로부터 비디오 프레임과 공간 정보를 캡처
people-analysis.tistory.com
어떻게 표현할까?
처음에는 소리에 따라 눈이 내려 공간에 쌓이는 형태를 기획했습니다.
눈이 '쌓이기' 위해서는 공간상의 평면을 인식하고, 내린 눈의 위치 정보를 누적해 실시간으로 렌더링해야 했습니다.
이 과정에서 화면이 뚝뚝 끊기는 현상이 발생했고, 제한된 시간 내에 이를 최적화하기 어려워 다른 방식을 모색하게 되었습니다.
두 번째로는 사인파가 공간상에서 퍼져나가는 모습을 시각화하고자 했습니다. 그러나 평면상의 물결 움직임은 예상보다 공간과의 결합감을 주지 못했고, 구형파를 활용한 3차원 구현에서도 소리가 퍼져나가는 모습이 직관적으로 전달되지 않았습니다.
최종적으로 구형 입자를 사용하여 소리가 폭죽처럼 터져 공간상에 퍼지는 형태로 표현하기로 결정했습니다.
또한 사용자가 소리의 발원지를 자유롭게 조정할 수 있도록 별도의 핸들을 구현하여 위치 제어가 가능하게 했습니다.
어려웠던 점
프로젝트를 진행하면서 처음에는 당연히 오디오를 처리하고 이를 AR 위에 랜더링하는게 어려울것이라고 짐작했는데 생각보다 프레임워크단에서 제공하는 기능이 많아서 비교적 쉽게 해결할 수 있었습니다.
근데 앱을 처음 시작할 때 마이크 권한을 받으면 자꾸 앱이 끓기는 현상이 발생해서 이것을 해결하는데 3일 정도 소비했습니다. 어떻게 보면 앱의 핵심 기능도 아닌데 이런게 시간을 잡아먹으니까 이를 해결하는 과정에서 짜증도 많이 났습니다.
항상 코딩하는 단계에서 느끼는 건데 설계 때는 예상도 못했던 지점에서 많은 시간을 잡아 먹습니다.
아쉬운 점
원래는 Metal 프레임워크를 활용해 직접 시각적 효과를 만들고 GPU를 통한 렌더링 및 최적화를 하려 했습니다.
하지만 Metal 프레임워크의 렌더링 파이프라인, 그래픽스 개념, 그리고 Swift와 Metal 간의 브릿지에 대한 이해가 부족해 시도하다 포기하고 SceneKit에서 제공하는 기본 효과를 사용하게 되었습니다.
향후에는 Metal 프레임워크에 대한 깊은 이해를 바탕으로 최적화된 다양한 시각 효과를 직접 구현해보고 싶습니다.
또한 현재는 분석한 소리를 각 주파수별로 색상에 매핑하는 방식을 사용했지만, 음악의 박자 등 더 다양한 음악적 요소를 시각화에 활용하고 싶습니다.