잡담

오디오 프로그래밍에 대해서 – 1

요즘 자체 오디오 플레이어 및 휴대기기 음악 파일 싱크를 위해서 앱을 만들어보려고 삽질을 좀 했다.

어차피 WPF로 프론트엔드를 개발할 거, NAudio나 CSCore같은 라이브러리를 사용할까 했는데 결국 좀 더 다양한 파일 포맷을 재생할 수 있으려면 네이티브로 개발한 후에 C#용 래퍼를 만드는게 답인 것 같아서 C++로 라이브러리를 만들어보기로 했다.

Media Foundation이야 뭐 원래 사용해왔던 API고, XAudio 2도 사용을 안 해본 API는 아니기 때문에 이 API들로 기본적인 인터페이스는 만들었는데, 여기에 WASAPI(Windows Audio Session API) 재생 기능도 만들어보려고 했는데 의외의 복병이 바로 WASAPI였다.

WASAPI는 독점모드 재생이 가능하기 때문에 오디오 믹싱 처리를 안 하고 바로 원음을 재생할 수 있다는 장점이 있지만 문제가 있다. 바로 리샘플링 기능을 제공하지 않는다는 점.

리샘플링이 지원되지 않으면 무조건 시스템 재생 장치의 설정을 그대로 따라가는 음원만 재생이 가능하다. 예를 들면, 시스템 재생 장치의 샘플 속도 및 비트 수준 설정이 16비트에 48000Hz인 경우, 재생 가능한 음원은 무조건 16비트에 48000Hz 음원만 재생이 가능한 것이다. 이 경우 16비트에 44100Hz 음원은 재생이 불가능하다.

그렇다면 WASAPI로 재생하는 음악 재생 프로그램들은 어떻게 음원을 재생할 수 있는가 하면 프로그래머가 리샘플링을 알아서 한다. Windows에서는 이 리샘플링을 위한 API로 DMO(DirectX Media Object)를 제공한다. WASAPI와 DMO 모두 Windows 기본 API라는 것을 생각한다면 굳이 WASAPI에서 리샘플링을 기본 제공하지 않을 이유가 없었다는 것을 알 수 있겠지. 이건 마이크로소프트의 설계상 문제였다고 생각한다. 하나만 생각하고 둘은 생각 안 한 그런.

DMO로 리샘플링하는 예제도 찾질 못해서 진짜 겨우겨우 구현했다. NAudio랑 CSCore에 구현된 DMO 리샘플러 소스코드를 뜯어보고 거기에서 사용한 인터페이스의 UUID값 찾느라 너무 힘들었음. 결국 정답은 MSDN에 있긴 했지만 그 방대한 문서들 사이에 해당 문서로 가는 링크를 못찾아서 문제였다.

이제 OpenAL 및 DirectSound 오디오 플레이어도 구현하고 LimeMP3나 FAAD2, libogg/libvorbis/libFLAC/opus를 이용해서 오디오 디코더도 구현해야 되는데 너무 힘들다. 일단 좀 쉬어야지.

광고

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

This site uses Akismet to reduce spam. Learn how your comment data is processed.