월패드 개발 과정에서 가장 오래 붙잡고 있었던 문제 중 하나가 X30 보드에서 음성이 정상적으로 출력되지 않는 현상이었습니다.
처음에는 단순히 애플리케이션의 오디오 설정 문제라고 생각했습니다. 영상 통화 화면은 정상적으로 표시되고 SIP 연결도 이루어졌기 때문에, 소프트웨어에서 AudioManager 설정이나 볼륨, mute 상태 정도만 확인하면 해결될 것으로 예상했습니다.
하지만 실제로는 생각보다 확인해야 할 범위가 훨씬 넓었습니다.
1. SIP 연결과 영상은 정상인데 음성만 나오지 않는 문제
초기 증상은 다음과 같았습니다.
- SIP 호출 및 연결은 정상
- 상대방 영상 수신 정상
- 통화 상태 전환 정상
- 마이크 및 스피커 관련 API 호출도 정상
- 로그상 오류 없음
- 실제 보드에서는 음성이 출력되지 않음
특히 소프트웨어 로그에는 특별한 오류가 남지 않았기 때문에 처음에는 원인을 찾기가 쉽지 않았습니다.
2. 첫 번째 시행착오 - Android 볼륨 및 AudioManager 확인
가장 먼저 Android의 AudioManager 설정을 확인했습니다.
STREAM_VOICE_CALL, STREAM_MUSIC, MODE_IN_COMMUNICATION 등의 값을 변경하면서 출력 경로를 강제로 지정해 보았습니다.
스피커폰 활성화, 음소거 해제, 볼륨 최대 설정 등 일반적인 Android 음성 출력 문제에서 확인할 수 있는 부분을 모두 점검했습니다.
하지만 X30 보드에서는 큰 변화가 없었습니다.
이 과정에서 일반 스마트폰의 오디오 구조와 월패드 전용 보드의 오디오 구조가 동일하지 않을 수 있다는 점을 다시 확인하게 되었습니다.
3. 두 번째 시행착오 - SIP Answer 시점과 Audio Bridge
다음으로 의심했던 부분은 SIP 통화 수락 과정이었습니다.
영상 화면이 표시되는 시점과 실제 음성 스트림이 시작되는 시점이 서로 다를 수 있었기 때문에 SIP Answer 처리 순서를 변경해 보았습니다.
처음에는 영상 연결과 동시에 모든 오디오를 활성화했지만, 이후에는 다음과 같이 단계를 나누어 처리했습니다.
- 호출 수신
- 영상 먼저 연결
- 사용자가 통화를 수락
- SIP Audio 활성화
- Audio Bridge 시작
- Mute 해제
- 실제 출력 장치 확인
특히 sipAnswerVideoOnly 형태로 먼저 영상을 연결한 후 사용자가 통화를 수락했을 때 sipAnswer와 sipStartAudioBridge를 호출하도록 구조를 변경했습니다.
이 방식으로 SIP 상태 관리는 훨씬 안정적으로 바뀌었지만 여전히 실제 스피커 출력 문제는 완전히 해결되지 않았습니다.
4. 세 번째 시행착오 - 소프트웨어가 아니라 하드웨어 출력 경로 확인
여기서부터 접근 방향을 바꾸게 되었습니다.
Android 애플리케이션 내부에서 음성 데이터가 생성되고 있다는 사실과 실제 물리적인 스피커에서 소리가 나오는 것은 별개의 문제였습니다.
X30 보드가 사용하는 오디오 출력 경로와 월패드 내부 앰프 구성을 다시 확인했습니다.
확인 과정에서는 다음 항목들을 점검했습니다.
- 보드 Audio Codec
- 스피커 출력 채널
- 앰프 Enable 신호
- GPIO 제어 여부
- Line Out / Speaker Out 구분
- 하드웨어 믹서 설정
- ALSA Mixer 상태
- Android Audio HAL 경로
- 음성 통화 스트림이 실제 어느 Device로 Routing 되는지
앱에서 정상적으로 음성을 재생하고 있어도 앰프가 활성화되지 않거나 Audio Route가 다른 출력 장치로 지정되어 있으면 실제 스피커에서는 아무 소리도 나지 않을 수 있었습니다.
5. 앰프 연동 확인
결국 중요한 부분은 월패드 장비 자체의 앰프 연동이었습니다.
X30 보드에서 생성된 오디오가 실제 월패드 스피커로 전달되기 위해서는 단순한 Android 스피커 출력뿐만 아니라 장비 내부 앰프가 정상적으로 활성화되어야 했습니다.
이 과정에서 소프트웨어 출력, 하드웨어 출력, 앰프 제어를 각각 분리해서 확인했습니다.
테스트 음원을 직접 재생해 보고, SIP 음성과 비교하면서 어느 구간까지 신호가 전달되는지 하나씩 확인했습니다.
이렇게 구간별로 문제를 나누니 원인을 훨씬 빠르게 좁힐 수 있었습니다.
6. TTS 방송 기능까지 확장
음성 출력 경로가 안정화된 이후에는 동일한 구조를 활용해 TTS 방송 기능도 연동했습니다.
서버 또는 월패드에서 전달받은 텍스트를 음성으로 변환하고, 앰프를 활성화한 뒤 실제 장비 스피커를 통해 방송하도록 구성했습니다.
결과적으로 단순한 SIP 통화 음성뿐 아니라 안내 방송, 상태 알림, 이벤트 음성 출력 등으로 확장할 수 있는 구조를 만들 수 있었습니다.
7. 이번 문제에서 배운 점
이번 문제는 처음부터 애플리케이션 코드만 확인했으면 훨씬 오래 걸렸을 문제였습니다.
임베디드 월패드 환경에서는 Android 애플리케이션, SIP 라이브러리, Audio HAL, 보드의 Audio Codec, GPIO, 앰프까지 하나의 오디오 경로로 연결되어 있습니다.
따라서 음성 문제가 발생했을 때는 다음과 같이 구간을 나누어 확인하는 것이 효과적이었습니다.
애플리케이션
→ SIP Audio Stream
→ Android Audio Framework
→ Audio HAL
→ Codec
→ Amplifier
→ Speaker
각 단계마다 실제 신호가 존재하는지 확인하면 막연하게 코드를 수정하는 것보다 훨씬 빠르게 원인을 찾을 수 있습니다.
이번 작업을 통해 월패드처럼 소프트웨어와 하드웨어가 함께 동작하는 환경에서는 로그만으로 판단하지 않고 실제 장비의 출력 경로까지 함께 확인해야 한다는 점을 다시 경험했습니다.
문제가 해결된 이후에는 SIP 통화 음성뿐 아니라 TTS 안내 방송까지 동일한 오디오 출력 구조를 활용할 수 있게 되었고, 이후 비슷한 장비를 연동할 때도 재사용할 수 있는 기준을 만들 수 있었습니다.