경고: OpenSL ES는 지원 중단되었습니다. 개발자는 GitHub에서 제공되는 오픈소스 Oboe 라이브러리를 사용해야 합니다. Oboe는 AAudio와 매우 유사한 API를 제공하는 C++ 래퍼입니다. Oboe는 AAudio를 사용할 수 있는 경우 AAudio를 호출하고 사용할 수 없는 경우에는 OpenSL ES로 대체합니다.
이 섹션에서는 OpenSL ES API를 사용하는 데 필요한 정보를 제공합니다.
앱에 OpenSL ES 추가
C 및 C++ 코드 모두에서 OpenSL ES를 호출할 수 있습니다. 앱에 핵심 OpenSL ES 기능 집합을 추가하려면 OpenSLES.h
헤더 파일을 포함합니다.
#include <SLES/OpenSLES.h>
OpenSL ES Android 확장 프로그램도 추가하려면 OpenSLES_Android.h
헤더 파일을 포함합니다.
#include <SLES/OpenSLES_Android.h>
OpenSLES_Android.h
헤더 파일을 포함하면 다음 헤더는 자동으로 포함됩니다.
#include <SLES/OpenSLES_AndroidConfiguration.h> #include <SLES/OpenSLES_AndroidMetadata.h>
참고: 위 헤더는 필수 항목은 아니지만 API 학습 도우미로 표시됩니다.
빌드 및 디버그
NDK 빌드 시스템의 makefile 중 하나인 Android.mk
파일에 OpenSL ES를 지정하여 빌드에 포함할 수 있습니다. Android.mk
에 다음 줄을 추가합니다.
LOCAL_LDLIBS += -lOpenSLES
강력한 디버깅을 위해 대부분의 OpenSL ES API가 반환하는 SLresult
값을 검사하는 것이 좋습니다. 디버깅에 어설션 또는 고급 오류 처리 로직을 사용할 수 있습니다. 지정된 사용 사례에 둘 중 어느 하나가 더 적합할 수는 있지만 둘 다 OpenSL ES 사용 시 고유한 이점은 없습니다.
예시에서는 어설션을 사용했는데, 이는 어설션이 코딩 오류를 나타내는 비현실적 조건을 포착하는 데 유용하기 때문입니다. 프로덕션 환경에서 발생할 가능성이 높은 다른 조건에는 명시적 오류 처리를 사용했습니다.
여러 API 오류의 경우, 0이 아닌 결과 코드 외에 로그 항목이 표시됩니다. 로그 항목은 Engine::CreateAudioPlayer
와 같이 상대적으로 복잡한 API에 특히 유용한 추가 세부정보를 제공할 수 있습니다.
명령줄 또는 Android 스튜디오에서 로그를 볼 수 있습니다. 명령줄에서 로그를 검토하려면 다음을 입력합니다.
$ adb logcat
Android 스튜디오에서 View > Tool Windows > Logcat을 선택합니다. 자세한 내용은 Logcat을 이용한 로그 작성 및 보기를 참조하세요.
예시 코드
코드의 모델로 사용할 수 있도록 테스트를 마친 후 지원되는 예시 코드를 사용하는 것이 좋습니다. 이 예시 코드는 android-ndk GitHub 저장소의 audio-echo 및 native-audio 폴더에 있습니다.
주의: The OpenSL ES 1.0.1 사양의 경우 예시 코드는 부록에 있습니다(자세한 내용은 Khronos OpenSL ES 레지스트리 참조). 하지만 부록 B: 샘플 코드 및 부록 C: 사용 사례 샘플 코드의 예에서는 Android에서 지원하지 않는 기능을 사용합니다. 또한 일부 예시에는 철자 오류가 포함되어 있고, 아니면 변경될 가능성이 있는 API를 사용합니다. 이러한 예시를 참조할 때는 주의하여 진행하세요. 코드가 OpenSL ES 표준을 완전히 이해하는 데 도움이 될 수는 있지만 Android에서 그대로 사용해서는 안 됩니다.
오디오 콘텐츠
애플리케이션에 맞게 오디오 콘텐츠를 패키징할 수 있는 여러 방법 중 몇 가지가 아래 나와 있습니다.
- 리소스: 오디오 파일을
res/raw/
폴더에 두면Resources
의 연결된 API에서 손쉽게 이 오디오 파일에 액세스할 수 있습니다. 하지만 리소스의 직접적인 네이티브 액세스가 제공되지 않기 때문에 자바 프로그래밍 언어 코드를 작성하여 리소스를 사용하기 전에 복사해야 합니다. - 애셋: 오디오 파일을
assets/
폴더에 두면 Android 네이티브 Asset Manager API에서 직접 이 오디오 파일에 액세스할 수 있습니다. 이러한 API에 관한 자세한 내용은 헤더 파일android/asset_manager.h
및android/asset_manager_jni.h
를 참조하세요. android-ndk GitHub 저장소에 있는 예시 코드에서는 다음과 같은 네이티브 Asset Manager API를 Android 파일 설명자 데이터 로케이터와 함께 사용합니다. - 네트워크: URI 데이터 로케이터를 사용하여 네트워크에서 직접 오디오 콘텐츠를 재생할 수 있습니다. 단, 보안 및 권한을 반드시 읽어야 합니다.
- 로컬 파일 시스템: 애플리케이션에서 로컬 파일에 액세스할 수 있는 경우 URI 데이터 로케이터는 이 로컬 파일에
file:
구성표를 지원합니다. Android 보안 프레임워크는 Linux 사용자 ID 및 그룹 ID 메커니즘을 통해 파일 액세스를 제한합니다. - 녹음됨: 애플리케이션은 마이크 입력 장치의 오디오 데이터를 레코딩하고 이 콘텐츠를 저장한 다음 나중에 재생할 수 있습니다. 예시 코드에서는 재생 클립에 이 방법을 사용합니다.
- 컴파일 및 연결된 인라인: 오디오 콘텐츠를 공유 라이브러리에 직접 연결한 다음 버퍼 큐 데이터 로케이터가 있는 오디오 플레이어를 사용하여 재생할 수 있습니다. 이는 짧은 PCM 형식 클립에 가장 적합합니다. 예시 코드에서는 Hello 및 Android 클립에 이 기법을 사용합니다.
bin2c
도구(제공되지 않음)를 사용하여 PCM 데이터를 16진수 문자열로 변환했습니다. - 실시간 합성: 애플리케이션은 필요에 따라 즉시 PCM 데이터를 합성한 다음 버퍼 큐 데이터 로케이터가 있는 오디오 플레이어를 사용하여 재생할 수 있습니다. 오디오 합성은 비교적 고급 기법이기 때문에 이에 관한 세부정보는 이 문서에서 다루지 않습니다.
참고: 애플리케이션에 유용한 오디오 콘텐츠를 검색하거나 생성하는 작업은 이 문서에서 다루지 않습니다. 자세한 정보를 찾으려면 대화형 오디오, 게임 오디오, 사운드 디자인, 오디오 프로그래밍 등의 웹 검색어를 사용하세요.
주의: 콘텐츠 재생 또는 레코딩이 법적으로 허용되는지 확인하는 것은 개발자의 책임입니다. 콘텐츠 레코딩에 관한 개인정보 보호정책을 고려해야 할 수도 있습니다.
코드 샘플
이러한 샘플 앱은 GitHub 페이지에서 이용할 수 있습니다.
- audio-echo는 입력-출력 왕복 루프를 생성합니다.
- native-audio는 단순 오디오 레코더/플레이어입니다.
OpenSL ES의 Android NDK 구현은 여러 측면에서 OpenSL ES 1.0.1의 참조 사양과 다릅니다. 이러한 차이는 OpenSL ES 참조 사양에서 직접 복사한 샘플 코드가 Android 앱에서 작동하지 않을 수 있는 중요한 이유입니다.
참조 사양과 Android 구현 간 차이점에 관한 자세한 내용은 Android용 OpenSL ES를 참조하세요.