Wwise SDK 2021.1.14
스트리밍 / 스트림 매니저
|
Wwise SDK 2021.1.14
|
소개
제한된 대역폭 때문에 게임에서 저장 장치로 접근시 병목현상이 자주 발생할 수 있습니다. 따라서, 데이터 전송 요청을 순서대로 유지하기 위해 일반적으로 게임 타이틀이 I/O에 접근하도록 합니다. 이 순서는, 전송 크기 및 처리량과 레이턴시와 관련해 소비자 요구 사항과 상대적 우선 순위를 기반으로 합니다. 오디오는 대개 I/O 사용이 많습니다. 음악과 긴 사운드들은 재생했을 때 주로 디스크로부터 스트리밍되기 때문입니다.
Audiokinetic의 I/O 스트리밍 솔루션
Audiokinetic 사운드 엔진의 I/O 스트리밍 솔루션은 자율적이고 오버라이드 가능한 스트리밍 관리 모듈로 구성돼있습니다. 다음 그림은 이 모듈과 사운드 엔진 및 게임 아키텍처 내에서의 위치를 나타내는 블록 다이어그램입니다.
IAkStreamMgr.h 에 정의된 해당 공용 인터페이스는 사운드 엔진과 게임 둘 다에서 사용할 수 있도록 고안되었습니다. 사운드 엔진은 이 인터페이스를 사용해 SoundBank를 로드하고 오디오 파일을 스트리밍합니다. 게임은 그래픽이나 텍스처, 레벨, 저장된 게임 등을 로드할 때 이 인터페이스를 사용합니다.
공용 인터페이스는, 플랫폼의 운영 체제나 하드웨어와 밀접한 파일이나 오브젝트 처리를 소위 '스트림'이라는 것으로 감싸서 저장 (I/O) 장치간 데이터 전송을 하기 위한, 플랫폼별로 독립적인 상위 레벨 추상화입니다. 이 문서에서 등장하는 스트림 오브젝트와 스트림 팩토리를 구현하는 모듈은 High-Level Stream Manger나 단순한 Stream Manager를 지칭합니다.
필요하다면 Stream Manager 전체를 오버라이드할 수 있지만, Wwise SDK에는 기본 구현이 나와있습니다. 이 기본 구현은 자신의 I/O 관련 코드와 함께 쓰도록 또 다른 레벨을 정의하는 Low-Level I/O라는 것이 있어 훨씬 쉽게 사용할 수 있습니다. Wwise I/O를 자신의 게임에 통합시킬 때 이 방법을 추천합니다.
|
Default Streaming Manager Information
AK::StreamMgr::Create() 와 같이 스트리밍과 관련돼있으나 Stream Manager의 기본 구현에 특화된 함수와 구조체들은 SDK의 포함 디렉터리 내 AkStreamMgrModule.h 에서 정의돼있습니다. |
Wwise I/O 통합
빠르게 통합하기
Wwise를 처음으로 통합할 때 빠르게 할 수 있는 방법은, 기본 Stream Manager와 Wwise SDK에 있는 하위 레벨 I/O 샘플을 사용하는 것입니다.
1) AkStreamMgr.lib 와 연결.
2) 기본 File Location Resolver와 Blocking I/O Hook를 개발하는 게임 프로젝트에 포함시킴.
- SDK/Samples/SoundEngine/{Platform name}/AkDefaultIOHookBlocking.h and .cpp
- SDK/Samples/SoundEngine/{Platform name}/AkFileHelpers.h
- 모든 파일은 SDK/Samples/SoundEngine/Common/ 에 있음.
3) Stream Manager를 생성한 다음, 해당 하위 레벨 I/O 후크 장치 CAkDefaultIOHookBlocking를 인스턴스로 만들고 초기화합니다. 이 때, I/O 후크의 File Package 확장을 구현하는 CAkFilePackageLowLevelIOBlocking를 써도 됩니다 (다음 섹션 참고). 결국 필요하게 될 때 사용할 준비가 돼있을 것입니다. 초기화 예제를 보려면 스트리밍 매니저의 초기화 를 참고하세요.
4) 기본 File Location Resolver(CAkFileLocationBase에 구현)에게 Wwise 저작 툴이 생성한 파일의 디렉터리를 알려줘야 합니다. 자신의 코드에서 CAkDefaultIOHookBlocking::SetBasePath() (또는 CAkDefaultIOHookBlocking::AddBasePath() )를 이용해 오디오 에셋이 배포되는 기본 경로를 설정합니다. 현지화된 에셋이 있을 경우, AK::StreamMgr::SetCurrentLanguage() 를 이용해 기본 Stream Manager 모듈에 현재 언어를 설정하세요. 기본 File Location Resolver는 현지화된 에셋을 찾기 위해 언어 이름을 기본 경로에 연결시킵니다.
![]() |
주의: AK::StreamMgr::SetCurrentLanguage() 로 전달하는 언어 이름에 디렉터리 구분자(슬래시나 역슬래시)를 붙이지 마세요. |
이제 사운드 엔진이 사운드뱅크를 로드하고 SetBasePath()(또는 AddBasePath() )에 지정한 디렉터리로부터 스트리밍된 파일을 재생할 준비가 되었습니다. Wwise 툴에서 사운드뱅크 출력 디렉터리에 스트림 파일을 자동으로 복사하려면 사운드뱅크 생성 후 'CopyStreamedFiles' 실행 파일을 사용해야 합니다. 더 자세한 내용은 Wwise 도움말에 나와있는 'SoundBank 설정' 부분을 참고하세요.
파일 패키지
CAkFilePackageLowLevelIOBlocking 장치를 인스턴스화했다면 몇 단계만 거치면 파일 패키지를 사용할 준비를 마치게 됩니다. 파일 패키지(*.PCK)는 Wwise 프로젝트의 모든 사운드뱅크와 스트리밍 오디오 파일의 연결로 만들어진 단일 파일입니다. 서로 다른 파일 패키지에 사운드뱅크와 스트리밍 파일을 할당할 수도 있습니다. 더 자세한 내용은 File Packager 유틸리티 문서를 참고하세요.
1) 사운드뱅크 생성 후 'FilePackager' 실행 파일을 이용해 Wwise 툴이 해당 사운드뱅크와 스트리밍 파일로 파일 패키지를 자동으로 생성하게 합니다 (Wwise 도움말의 'SoundBank 설정' 부분 참고).
2) 자신의 코드에서, CAkFilePackageLowLevelIOBlocking::LoadFilePackage()를 명시적으로 사용해 파일 패키지를 로드합니다. LoadFilePackage()가 SetBasePath()(또는 AddBasePath() )에 지정된 경로로부터 파일 패키지를 엽니다. 오디오 에셋의 배포 디렉터리에 자신의 파일 패키지를 포함시키되, 그 안에 들어있는 사운드뱅크와 스트리밍된 파일은 넣지 않습니다. 파일 패키지를 로드할 때, 해당 헤더가 파싱되고 CAkFilePackageLowLevelIOBlocking 안에 조회 테이블이 생성됩니다. 사운드 엔진이 파일을 열 때, AK::SoundEngine::LoadBank() 호출이나 스트리밍된 파일의 재생을 수반하는 이벤트 후 CAkFilePackageLowLevelIOBlocking가 로드된 모든 파일 패키지의 조회 테이블에서 해당 파일을 탐색합니다. 파일이 검색되지 않으면 기본 경로에서 해당 파일을 검색합니다.
I/O 읽기 요청을 자신의 I/O 관리자로 보내기
CAkDefaultIOHookBlocking 는 플랫폼 파일 시스템 API를 이용해 파일을 읽습니다. 자신의 게임 엔진에 이미 I/O 관리자가 관리자가 있는 경우, Wwise Stream Manager에서 발생한 I/O 읽기 요청을 자신의 I/O 관리자에게 전송할 수 있습니다. 플랫폼 파일 시스템이 아니라 자신의 I/O 관리자를 호출하도록 CAkDefaultIOHookBlocking::Read()를 변경합니다. 필요한 경우 CAkDefaultIOHookBlocking::Open()를 변경할 수도 있습니다.
그 외 사용 안내: Low-Level I/O 다루기
SDK에서 제공하는 기본 Stream Manager 구현은 Low-Level I/O라는 하위 모듈에 있습니다. 위에 설명한 클래스들은 모두 Wwise SDK 안에 Low-Level I/O 예제 구현으로 나와있습니다. 관련 파일들은 기본 Low-Level I/O 구현 에서 찾을 수 있습니다.
Wwise I/O를 자신의 게임 엔진에 통합하는 방법으로는, Low-Level I/O 레이어를 Wwise I/O와 자신의 I/O 처리 기술 간에 어댑터로서 구현하는 방법이 많이 사용됩니다. 게임 내 Low-Level I/O를 구현하는 방법은 간단한 것부터 복잡한 것까지 매우 다양하며 커스터마이징의 폭이 큽니다. 처음인 경우, 예제를 사용해보는 것도 좋은 방법이 될 수 있습니다.
Low-Level I/O 모듈의 목적은 두 가지입니다.
- 디스크에서 파일 위치를 결정합니다: Wwise가 생성한 파일은 게임 디스크에서 어디든 위치할 수 있지만, 코드를 작성할 때 플랫폼의 파일 시스템이 사용하는 파일 설명자에 반드시 SoundBank와 스트리밍 파일 이름과 ID 간 올바른 매핑을 해줘야 합니다.
- 모든 하위 레벨 I/O 작업을 추상화합니다: Stream Manager로 스케줄 된 모든 I/O 전송 요청(읽기/쓰기)이 전달됩니다.
Wwise I/O 성능
Stream Manager의 초기화 설정은 자신의 Low-Level I/O 시스템과 상호작용하는 방식과 전반적인 I/O 성능에 영향을 끼칩니다. Audiokinetic Stream Manager 초기화 설정 에 자세한 설명이 나와있습니다. I/O 도움말, 문제 해결 및 최적화 를 참고하면 이를 변경하는 방법에 대한 도움말을 볼 수 있습니다.
High-Level Stream Manager
Stream Manager의 인터페이스는 IAkStreamMgr.h 에 정의돼있으며, Wwise 사운드 엔진에서 이를 사용해 사운드뱅크와 스트리밍된 오디오 파일을 읽습니다. 만약 자신의 I/O 관리자가 없는 경우, 이를 모든 게임 I/O에 사용할 수도 있습니다. 마찬가지로, 커스텀 음원 플러그인을 작성할 경우 Stream Manager에 접근할 수 있습니다.
상위 레벨 Stream Manager API 설명 에 해당 API에 대해 자세한 설명이 나와있습니다. 클라이언트로서 Stream Manager를 직접 사용하지 않고 하위 레벨 I/O 연결을 구현해 자신의 게임에 Wwise I/O를 통합하기만 하는 경우라면 이번 장을 건너뛰어도 됩니다.
다음은 몇 가지 기본 개념입니다. Stream Manager는 표준 스트림과 자동 스트림, 이 두 가지 데이터의 추상 스트리밍을 관리합니다.
- 표준 스트림 (AK::IAkStdStream): 표준 스트림은 AK::IAkStdStream::Read() or AK::IAkStdStream::Write() 호출이 발행됐을 때 필요에 따라 Stream Manager로 I/O 요청을 발송합니다. I/O 는 사용자가 지정한 메모리 내에서 처리됩니다.
- 자동 스트림 (AK::IAkAutoStream): 자동 스트림은 내부 스트리밍 메모리로부터 주소를 부여하여 AK::IAkAutoStream::GetBuffer() / AK::IAkAutoStream::ReleaseBuffer() 메소드로 데이터에 접근합니다. 주요 인터페이스인 AK::IAkStreamMgr 는 스트림 팩토리의 역할을 합니다. 자동 스트림은 내부적으로 메모리를 관리하고, I/O 요청은 메모리에 작성할 여유가 생겼을 때 Low-Level IO에 자동으로 전달됩니다.
Stream Manager는 스레드로부터 안전하게끔 고안되었으나, 단 하나의 스레드만 스트림을 소유할 수 있습니다.
주요 인터페이스인 AK::IAkStreamMgr 는 AK::IAkStreamMgr::Get() 를 호출하면 어디서든 접근할 수 있습니다. 여기서 스트리밍 오브젝트를 생성하고 사용할 수 있습니다.
추가 정보
다음은 스트리밍에 대한 더 자세한 정보입니다.
이 페이지가 도움이 되었나요?
작업하는 프로젝트에 대해 알려주세요. 언제든지 도와드릴 준비가 되어 있습니다.
프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.
Wwise를 시작해 보세요
