Wwise SDK 2024.1.0
|
Wwise 사운드 엔진에서 Events와 Game Syncs로 사운드 재생을 제어합니다. 이러한 요소들은 SoundBank에 저장된 내부 사운드 구조체를 참조하는데, 결국에는 루즈 미디어 파일(loose media file)을 참조하게 됩니다. 사용하기 전에 전부 다 사운드 엔진에 의해서 로드되어야 합니다.
참고: PrepareEvent는 메모리 내 데이터를 사용하여 LoadBank와 호환되지 않습니다. |
SoundBank를 암묵적으로나 명시적으로 로드할 수 있습니다. 아래에서 자세히 나오는 두 가지 접근방법 모두 특정 시나리오에 따라 평가되어야 하는 장단점을 가지고 서로 다른 옵션을 제공합니다.
사운드 엔진 API의 AK::SoundEngine::LoadBank() 메소드 중 하나를 사용해 SoundBank를 명시적으로 로드할 수 있습니다. SoundBank가 로드되면 그 안의 모든 객체는 사용할 준비를 마칩니다.
다음 예제에서 SoundBank BANK_01은 명시적으로 로드되었습니다. 이 SoundBank는 Wwise_IDs.h 헤더 파일에 정의된 ID로 식별됩니다. 문자열(유니코드 또는 ANSI)이나 ID를 사용한 SoundBank의 식별에 관련된 내용은 뱅크의 식별 을 참고하세요. 해당 SoundBank는 관련 사운드 구조체 및 미디어와 함께 PLAY_SOUND_01 Event를 포함합니다 (Wwise로 SoundBank 생성하기와 관련된 더 많은 정보는 Wwise 도움말을 참고하세요). SoundBank가 로드되면 해당 이벤트가 사운드 엔진에 전달됩니다.
PrepareEvent/PrepareGameSync API는 SoundBank에 포함되지 않은 미디어 로딩을 암묵적으로 허용합니다. 이를 처리하기 위해서는 먼저 LoadBank()를 통해 명시적으로 Event와 Game Sync의 정의를 포함하는 SoundBank를 로드해야 합니다. 일반적으로 이러한 SoundBank는 이벤트와 구조체만 포함하며, 미디어는 포함하지 않아 매우 가볍습니다. 미디어 데이터 없이 SoundBank를 정의하는 방법에 대해 알기 위해서는 Wwise Help를 참고하세요. SoundBank에 참조하는 미디어가 포함되어 있지 않을 때에는 파일 시스템에서 루즈 미디어 파일을 통해 이용 가능해야 합니다. Event와 Game Sync의 정의를 로드한 후, 이를 사용하기 위해서 "준비"가 필요합니다. (AK::SoundEngine::PrepareEvent()와 AK::SoundEngine::PrepareGameSyncs()) Event와 Game Sync가 준비되면, 사운드 엔진은 암묵적으로 파일 시스템로부터 참조된 미디어 파일을 가져오게 됩니다. 이벤트 정의와 다르게 서로 다른 SoundBank에 사운드 구조체를 포함하는 게 가능합니다. 그러고 나서 이벤트 SoundBank는 구조체 데이터를 포함하고 있는 뱅크의 참조자를 포함하게 되며, 해당 이벤트가 준비되면 참조된 SoundBank로부터 구조체는 암묵적으로 미디어와 함께 로드됩니다. 포함된 모든 구조체는 연결된 SoundBank로부터 로드되며, 이 구조체는 이벤트에 의해 참조되는 게 전부가 아닙니다. 이러한 이유로 이벤트와 구조체는 같은 SoundBank에 묶어놓는 게 더 실용적인 경우가 많습니다.
다음 예제에서 BANK_02 뱅크는 명시적으로 로드되며 참조되는 미디어는 암묵적으로 로드됩니다. 해당 뱅크는 PLAY_SOUND_02 이벤트의 정의와 관련된 사운드 구조체를 포함합니다. 이벤트와 연결된 미디어를 포함하고 있지 않아서, 일단은 준비가 되었음에도 불구하고 이벤트 배치를 실패하게 됩니다. 그래서 뱅크를 성공적으로 로드한 다음, 이벤트는 발송하기 전에 준비됩니다. 이벤트가 준비되면, 사운드 엔진은 이벤트를 성공적으로 발송하기 위해서 필요한 모든 미디어를 자동으로 로드하게 됩니다.
AK::SoundEngine::PrepareEvent 와 AK::SoundEngine::PrepareGameSyncs 의 사용 방법에 대한 더욱 완벽한 예제를 확인하려면, 다음 과정을 참고하세요.
뱅크 로딩은 사운드 엔진의 개별 스레드에서 처리됩니다. 메인 API의 모든 LoadBank(), PrepareEvent(), PrepareGameSyncs() 함수들은 동기화 및 비동기화 로딩 스키마를 통해 이용 가능합니다.
동기화 함수 AK::SoundEngine::LoadBank()는 다른 함수들을 차단합니다. 이 함수는 뱅크가 로드되거나 오류가 발생했을 때 반환하게 됩니다.
비동기화 함수 AK::SoundEngine::LoadBank()는 즉시 반환되며, 매개 변수로 cookie를 가져서 필요한 행동을 완료하면 콜백 함수가 호출됩니다. 함수 호출이 비동기로 이뤄지면, 오류 처리는 콜백 함수에서 처리되어야 합니다.
cookie 매개 변수는 선택사항이며 편의에 따라 사용 가능합니다. 해당 매개 변수를 사용하지 않으면, 단순히 NULL를 넘겨줍니다. 사운드 엔진은 해당 포인터를 사용하지 않게 되며, 콜백 함수와 함께 반환될 뿐입니다.
LoadBank(), UnloadBank(), PrepareEvent(), PrepareGameSyncs()의 비동기 버전을 사용한 콜백 함수는 다음 원형을 따라야 합니다.
콜백 함수 구현의 책임이 있으며, 유효성을 보장해줘야 합니다.
매개 변수 in_bankID는, PrepareEvent와 PrepareGameSync에 대한 콜백을 받을 때에는 관련이 없으므로 무시합니다.
콜백 함수에 전달되는 매개 변수의 정의는 AkBankCallbackFunc를 참고하세요.
앞서 뱅크의 식별 에서 얘기했듯이 뱅크를 파일로부터 로드할 수 있는데, 하나의 포인터와 크기로 적절한 LoadBank()의 오버로드 함수를 제공할 수 있습니다. 또는, 뱅크 식별자(위에서 다룬 ID 또는 문자열)를 지정할 수 있습니다. 그러고 나서 스트림 매니저를 통해 사운드 엔진이 뱅크 파일을 로드하게 할 수 있습니다.
최종 위치에서 이미 메모리에 있는 뱅크를 로드하도록 LoadBankMemoryView()의 원형 중 하나를 사용합니다.
사운드 엔진 내에서 메모리는 복사되지 않기 때문에 뱅크가 언로드될 때까지 유효하도록 보장해줘야 합니다. 몇몇 정렬 제한은 어떤 뱅크가 로드되었는지 제공된 메모리 포인터의 플랫폼에 따라 적용될 수 있습니다. 모든 플랫폼에서 메모리는 AK_BANK_PLATFORM_DATA_ALIGNMENT 바이트로 정렬되어야 합니다. 몇몇 플랫폼은 다른 요구사항을 가지기 때문에 플랫폼 세부 SDK 문서를 확인해야 합니다.
또는, 임시 위치에서 메모리에 있는 뱅크를 로드하도록 LoadBankMemoryCopy()의 함수 원형 중 하나를 사용합니다.
해당 뱅크는 사운드 엔진에서 만든 새로운 할당에 복사되며, 전송된 포인터는 로드 작업이 끝나자마자 지워질 수 있습니다.
LoadBank()는 제공된 포인터의 맨 앞 몇 비트에 저장된 뱅크 ID를 파싱해서 반환합니다. 나중에 뱅크를 언로드하기 위해 뱅크 ID를 보관하세요.
참고: 사용자의 파일 I/O 처리를 사용해 사운드 엔진에 포인터를 넘겨주면, 반드시 명시적인 뱅크 로딩을 사용해야 합니다. 암묵적 뱅크 로딩은 예측이 불가능합니다. PrepareXXXX 명령문을 따라 몇 개의 뱅크를 로드할지, 이러한 뱅크들의 메모리 요구량에 대해 절대로 확신할 수 없습니다. 그 이유는 PrepareEvent와 PrepareGameSyncs의 내부 메모리용 버전이 없기 때문입니다. |
사운드 엔진은 파일로부터 읽어와야 할 필요가 있을 때마다 스트림 매니저를 사용합니다. 뱅크 식별과 I/O에 관련한 내용은 뱅크의 식별 을 참고하세요.
스트림 매니저와 관련해서 사운드 엔진의 뱅크 로더 처리를 손보기 위해서 AK::SoundEngine::SetBankLoadIOSettings()을 사용할 수 있습니다. I/O와 관련해서 더 많은 정보는 스트리밍 / 스트림 매니저 섹션을 참고하세요.
사운드 엔진은 뱅크들의 메타데이터를 파싱하고 사운드 엔진의 기본 풀에 해당 객체를 생성합니다.
I/O와 관련된 명시적 LoadBank() 함수에서, 미디어를 디스크로부터 읽어와 메모리로 복사합니다. I/O 작업 동안 뱅크는 사운드 엔진 초기화 설정인 AkInitSettings::uBankReadBufferSize 에서 지정한 크기의 묶음으로 읽어옵니다. 큰 값은 뱅크 I/O 작업 동안 메모리를 더 많이 사용하여 읽어 오기 또는 읽기 세트가 불가능합니다.
명시적으로 뱅크를 언로드할 수 있게 많은 수의 UnloadBank() 오버로드 함수가 있습니다.
마찬가지로 구조체의 레퍼런스 카운트 및 이벤트와 연결된 미디어를 줄이기 위해 Preparation_Unload 플래그와 함께 PrepareEvent() 함수를 사용합니다. 암묵적으로 로드된 뱅크 내 모든 객체의 레퍼런스 카운터가 0으로 떨어지면 자동으로 언로드됩니다.
또한, 특정한 게임 싱크가 선택되었을 때만 재생할 수 있는 사전에 준비된 이벤트에 대해 로드된 미디어를 다시 언로드하려면 Preparation_Unload 플래그와 함께 PrepareGameSyncs() 함수를 사용합니다. 게임 싱크는 레퍼런스 카운트를 갖지 않으며, Preparation_Unload 플래그로 한번 호출되면 참조되지 않은 미디어를 즉시 언로드합니다.
참고: 뱅크가 언로드될 때 해당 뱅크에 의해 참조되는 사운드가 재생중이면, 사운드 구조체를 포함할 경우 항상 재생을 중단합니다. 뱅크가 미디어만 포함하고 있으면 사운드를 중지할 수 있으며, 다른 로드된 뱅크는 미디어와 사운드 구조체를 가집니다. 이는 미디어가 첫 번째 데이터 아니면 그 다음 데이터 둘 중 어디서 재생되는지에 따라서 달라집니다. 뱅크 콘텐츠 복제 를 참고하세요. |
참고: 이벤트가 사운드 매개 변수의 수정에 사용되면(SetVolume 이벤트와 같이), 해당 정보는 제거됩니다. 만약 매개 변수가 RTPC나 state, switch를 사용해 변경되면, 해당 매개 변수가 메모리에 유지되며, SoundBank가 재 로드되면 자동으로 적용됩니다. |
다음 코드는 유니코드 문자열 식별자와 기본 뱅크 메모리 할당을 사용해 뱅크를 동기식으로 로드 및 언로드합니다. 또한, PrepareEvent()를 통해서도 암묵적으로 뱅크를 로드하고 언로드합니다.
LoadBank() 및 PrepareEvent() 함수를 통해 뱅크를 준비하는 것도 가능합니다. 다음 방법 중 하나를 사용해 뱅크를 준비할 수 있습니다.
이 두가지 방법은 구현 조금 다르게 해서 같은 PrepareBank 메커니즘을 사용하나, AkBankContent_All이 가장 일반적인 시나리오에서 사용됩니다. .
AkBankContent_All
을 사용해서 뱅크를 준비하면, PrepareEvent() 메커니즘의 장점을 취하면서 LoadBank() 메커니즘의 몇 가지 단점을 해결해 줍니다. 해당 메소드를 사용하면 SoundBank는 여전히 모든 콘텐츠 타입을 포함하고 있지만, 미디어 파일을 완전히 로딩하는 대신에, 이벤트 준비 메커니즘과 유사한 메커니즘을 사용해 모든 미디어를 메모리에 로드합니다. PrepareBank()로 미디어를 로딩할 때 Wwise는 맨 먼저 미디어 파일이 이미 메모리에 존재하는지 확인합니다. 이 방법은 메모리에 미디어 파일이 복제되는 것을 막아주기 때문에 메모리 사용량을 최소한으로 유지해줍니다.
AkBankContent_All 은 PrepareBank()를 위한 기본 로딩 메커니즘이며, 로드할 미디어 구성 요소의 뱅크를 검사합니다. 특정한 이벤트를 위한 미디어가 뱅크에 존재하지 않으면, 나중에 PrepareEvent()를 호출하여 루즈 파일로부터 로드될 수 있습니다.
AkBankContent_StructureOnly
로 PrepareBank()를 사용할 때, 이벤트와 구조체 메타데이터는 SoundBank로부터 로드되지만, 뱅크에 포함된 미디어 구성요소는 무시됩니다. PrepareEvent()는 반드시 디스크에서 루즈 파일 미디어에 접근해야 하며, SoundBank에 포함된 파일을 읽기가 불가능하기 때문입니다. AkBankContent_StructureOnly
는 몇 가지 다른 로딩 메커니즘을 사용해 다음번에 SoundBank도 로딩할 계획이 있을 때에만 유용합니다. PrepareEvent()로 미디어를 개별적으로 로딩하는지 대부분의 시나리오에서, 미디어는 뱅크에 포함되지 않아야 하며 AkBankContent_StructureOnly
플래그는 AkBankContent_All
와 같은 결과를 만들어 냅니다.
AkBankContent_StructureOnly
플래그의 유용한 점에 대한 한 가지 예로 여러 개의 로딩 환경설정을 구현하는 데 있습니다. 게임은 주문식 루즈 파일을 로드하도록 PrepareEvent()를 사용하는 "도구 모드"와 완전히 같은 뱅크를 로드하도록 LoadBank()를 사용하는 "게임 모드"를 가질 수 있습니다.
PrepareBank()는 API로부터 원하는 대로 동기식 또는 비동기식으로 호출될 수 있습니다. 그러나 같은 뱅크에 AkBankContent_All
과 AkBankContent_StructureOnly
둘 다 사용하는 것은 권장하지 않습니다. AkBankContent_All
을 사용해 미디어를 로드하면 언로드할 때 이벤트 및 구조체, 미디어 전부를 다 해제하기 때문입니다.
AK::SoundEngine::ClearBanks()
함수 호출은 사운드 엔진의 내용물을 제거하려고 할 때 유용합니다. SoundEngine::Term()
가 호출되기 전에 ClearBanks()
를 호출하면 안된다는 점을 기억하세요. ClearBanks
는 내부적으로 AK::SoundEngine::ClearPreparedEvents
를 호출합니다.
해당 함수가 호출되면:
AK::SoundEngine::ClearPreparedEvents() 함수의 호출은 현재까지 준비된 모든 이벤트의 준비를 해제하게 된다. 얼마나 많은 단일 이벤트가 준비되었는지는 상관없습니다. AK::SoundEngine::ClearPreparedEvents()
는 AK::SoundEngine::ClearBanks()
가 호출될 때 내부적으로 호출됩니다.
각 뱅크는 한 번만 로되될 수 있습니다. 뱅크를 다시 한번 명시적으로 로드하려고 하면, 뱅크 로드 오류가 발생하게 됩니다.
Wwise 사운드 엔진은 두 개 이상의 같은 이벤트나 사운드 구조체, 미디어를 갖는 걸 허용하며 동시에 전부 로드할 수 있습니다.
참고: For OpusNX, which do not support media relocation, if a sound that is common to several banks is being played, and the SoundBank from which it is being read is unloaded, this sound's playback will stop. 다른 로드된 SoundBank 중 하나에서 해당 사운드 인스턴스로의 전환은 없게 됩니다. |
PrepareEvent
를 사용했을 때, 서로 다른 이벤트에 대해서 같은 미디어 콘텐츠가 로드되도록 하려면 로드된 미디어는 메모리에서 복사되지 않아야 합니다. 여러 개의 이벤트는 같은 미디어 오브젝트를 참조할 수 있으며, 해당 미디어 오브젝트는 참조하는 모든 이벤트의 준비를 해제해야 언로드됩니다.
같은 미디어 콘텐츠를 로드하기 위해서 PrepareEvent
를 따라 LoadBank
사용은 미디어가 복제되는 문제가 발생할 것입니다. LoadBank를 사용했을 때 뱅크가 엔티티로 로드되기 때문입니다.
프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.
Wwise를 시작해 보세요