버전

menu_open
Wwise SDK 2023.1.3
마커 통합

소개

마커(marker)는 WAV 파일에 삽입돼 파형 내의 위치를 태그하는 데 쓰이는 식별자를 말합니다. 이 마커는 주로 SoundForge®나 Adobe® Audition®, CueTool 같은 WAV 편집기 애플리케이션에서 생성합니다.

애플리케이션에서는 이 마커를 통해 재생중 특정 지점에 도달했을 때 알림을 받게 됩니다. 예를 들어 재생중인 오디오와 싱크를 맞춰야 할 콘텐츠가 있는 경우나, Random Container로 어느 파일이 재생되고 있는지 확인해 올바른 자막을 게임에 나타내고자 할 때 사용합니다.

참고: Wwise 마커를 이용하면 립싱크와 자막을 매우 편리하게 통합할 수 있습니다.

WAV 파일 포맷으로 작업하기

청크(Chunk)는 큐 지점을 저장할 때 사용하는 데이터 스토리지 단위, 또는 큐 지점과 관련한 데이터를 말합니다. 큐 지점은 .wav 포맷 파일에 표시한 관심 지점을 말합니다.

큐 청크 (Cue Chunks)

큐 청크 포맷은 .wav 파일 내 관심 지점을 나타내는 마커의 위치를 저장하는 데 사용합니다.

오프셋 바이트 설명 값
0x00 4 청크 ID "cue " (0x63756520)
0x04 4 청크 데이터 크기 큐 지점의 개수에 따라 다름
0x08 4 큐 지점 개수 목록 내 큐 포인트 개수
0x0c 큐 포인트
#define CueID 'cue ' /* 큐 청크의 청크 ID */
typedef struct {
ID chunkID;
long chunkSize;
long dwCuePoints;
CuePoint points[];
} CueChunk;
typedef struct {
long dwIdentifier;
long dwPosition;
ID fccChunk;
long dwChunkStart;
long dwBlockStart;
long dwSampleOffset;
} CuePoint;

목록 청크 (List Chunks)

목록 청크는 .wav 파일 안의 컨테이너로, 하위청크를 포함하고 있습니다. 관련 데이터 목록 청크(adtl) 포맷은 큐 지점과 연관된 라벨과 노트, 텍스트를 저장하는 데 사용합니다.

오프셋 바이트 설명 값
0x00 4 청크 ID "list" (0x6C696E74)
0x04 4 청크 데이터 크기 포함된 하위 청크에 따라 다름
0x08 4 타입 ID "adtl" (0x6164746C)
0x0c SubChunks는 여기서부터 시작

라벨 하위 청크 (Label Sub-Chunk)

라벨 하위 청크 포맷은 큐 지점과 연관된 문자열을 저장하는 데 사용합니다. 관련된 데이터 목록 청크 안에 있어야 합니다.

오프셋 바이트 설명 값
0x00 4 청크 ID "labl" (0x6C61626C)
0x04 4 청크 데이터 크기 문자열 크기에 따라 다름
0x08 4 큐 지점 ID dwIdentifier 큐 청크를 참조함
0x0c Label (variable-size text)

Working with Source Plug-ins

Source plug-ins can also generate marker notifications.

음원 플러그인 내에서 AK::IAkPluginServiceMarkers::CreateMarkerNotificationService() 를 사용하여 AK::IAkPluginServiceMarkers::IAkMarkerNotificationService 의 인스턴스를 생성할 수 있습니다. 그런 다음 AK::IAkPluginServiceMarkers::IAkMarkerNotificationService::SubmitMarkerNotifications() 를 사용하여 AkAudioMarker 구조를 사용해 게임에 마커 알림을 보낼 수 있습니다.

{
AkUInt32 dwIdentifier; ///< Identifier.
AkUInt32 dwPosition; ///< Position in the audio data in sample frames.
const char* strLabel; ///< Label of the marker taken from the file.
AkUInt32 dwLabelSize; ///< Length of label read the from the file + terminating null character.
};

Marker Generator Source Plug-in Example

Below is an example of a source plug-in that generates marker notifications.

class MyMarkerGeneratorSourcePlugin : public IAkSourcePlugin
{
private:
IAkSourcePluginContext* m_pSourcePluginContext{};
IAkPluginServiceMarkers::IAkMarkerNotificationService* m_pMarkerNotificationService{};
AkUInt32 m_uElapsedSamples{};
static constexpr AkUInt32 g_uPayloadSize{ 64 };
char m_Payload[g_uPayloadSize]{};
// ...
public:
IAkPluginMemAlloc * in_pAllocator, ///< Interface to the memory allocator to be used by the plug-in
IAkSourcePluginContext * in_pSourcePluginContext, ///< Interface to the source plug-in's context
IAkPluginParam * in_pParams, ///< Interface to the plug-in parameters
AkAudioFormat & io_rFormat ///< Audio format of the output data to be produced by the plug-in (mono native by default)
) override
{
m_pSourcePluginContext = in_pSourcePluginContext;
m_pMarkerNotificationService = AK_GET_PLUGIN_SERVICE_MARKERS(m_pSourcePluginContext)->CreateMarkerNotificationService(m_pSourcePluginContext);
return AK_Success;
}
IAkPluginMemAlloc * in_pAllocator ///< Interface to memory allocator to be used by the plug-in
) override
{
AK_GET_PLUGIN_SERVICE_MARKERS(m_pSourcePluginContext)->TerminateMarkerNotificationService(m_pMarkerNotificationService);
return AK_Success;
}
void Execute(
AkAudioBuffer * io_pBuffer ///< In/Out audio buffer data structure (in-place processing)
) override
{
static constexpr AkUInt32 uNumMarkers{ 1 };
AkAudioMarker markers[uNumMarkers];
markers[0].dwIdentifier = 'mrkr';
markers[0].dwPosition = m_uElapsedSamples;
markers[0].strLabel = m_Payload;
markers[0].dwLabelSize = g_uPayloadSize;
const AkUInt32 offsetsInBuffer[uNumMarkers]{ 0 };
m_pMarkerNotificationService->SubmitMarkerNotifications(markers, offsetsInBuffer, uNumMarkers);
// advance the position of the markers
m_uElapsedSamples += io_pBuffer->MaxFrames();
}
// ...
};

마커 알림 사용 방법

여기서는 자신의 애플리케이션을 직접 설계해 마커 알림을 받는 방법에 대해 설명합니다.

  • 재생 이벤트를 게시할 때는 AK_Marker 플래그를 in_uiFlags 에 추가해야 합니다. 플래그는 비트별로 배타적이기 때문에, 이벤트 종료 알림을 받고자 하는 경우에는 AK_EndOfEvent | AK_Marker 를 사용해야 합니다.
AkUniqueID in_eventID, // 이벤트의 고유 ID
AkGameObjectID in_gameObjectID, // 연관된 게임 오브젝트 ID
AkUInt32 in_uFlags = 0, // Bitmask: AkCallbackType 참조
AkCallbackFunc in_pfnCallback = NULL, // Callback function
void * in_pCookie = NULL // 콜백 함수로 보낼 콜백 쿠키
// 및 이와 함께할 추가적 정보
);
  • 자신의 콜백 함수는 반드시 다음의 포맷이어야 합니다.
static void MarkersCallback(
AkCallbackType in_eType, // 콜백 타입으로, 여기서는 마커 이벤트를 받도록
// AK_Marker.
AkCallbackInfo* in_pCallbackInfo // 콜백 정보 구조체를 가리키는 포인터. 여기서는
// AkMarkerCallbackInfo*.
)
  • 콜백 함수가 호출되면 어떤 타입의 알림을 보낼 지 먼저 확인해야 합니다. 예를 들어 AK_Marker 알림만 처리하려는 경우, 다른 이벤트 타입을 받으면 반환해야 합니다.
  • 알림 타입에 따라 in_pCallbackInfo 를 적절한 정보의 구조체 타입으로 형변환해야 합니다. AK_Marker 알림의 경우, AkMarkerCallbackInfo 가 됩니다.
// AK_Marker에 해당하는 콜백 정보 구조체
{
AkUInt32 uIdentifier; // Cue point identifier
AkUInt32 uPosition; // Position in the cue point (unit: sample frames)
const char* strLabel; // Label of the marker (null-terminated)
AkUInt32 uLabelSize; // Size of the label string (including the terminating null character)
};
  • 나중에 참조할 경우를 위해 strLabel 문자열 멤버의 내용물을 복사하는 것을 잊지 마세요. 콜백이 반환된 후 포인터가 무효화될 수 있기 때문입니다.
참고
예제 통합으로 빠르게 시작하기 - 이벤트

알림 Notification Latency

현재는, 버퍼가 하드웨어로 전달될 때 알림을 보냅니다. 즉, 알림을 보낼 때와 마커에 도달했을 때 사이에 일정한 상수 지연이 있다는 것을 의미합니다. 이는, 애플리케이션이 마커와 관련된 정보를 모으고, 해당 마커에 연결된 사운드가 실제 재생되기 전에 이를 처리할 수 있는 충분한 시간이 됩니다.

이 지연 시간은 플랫폼별로 다르다는 점에 유의하세요.

콜백 스레드

마커의 콜백은, 이벤트 종료 알림 콜백과 마찬가지로 사운드 엔진의 주요 스레드에서 처리됩니다. 즉, 애플리케이션이 알림으로부터 필요한 모든 정보를 모은 후 즉각 반환해야한다는 뜻입니다. 만약 특정 처리가 필요한 경우, 알림으로부터 관련 정보를 복사해온 후 별도의 스레드에서 실행해야 합니다.

애플리케이션이 스레드를 너무 오래 붙잡고 있으면 사운드 엔진이 언더런(underrun) 상태로 들어가고 출력 재생이 중단될 수 있습니다.

주의
콜백 함수가 반환된 후 사운드 엔진이 참조 데이터를 해제하기 때문에 콜백 함수로부터 라벨 문자열을 복사해놔야 합니다.

Wwise 캡처 로그 및 마커

Wwise Profiler는 사운드 엔진으로부터 온 마커 알림을 표시합니다. 이를 위해 Profiler Settings 대화창에서 Markers Notification Data 옵션이 반드시 활성화돼있어야 합니다. 마커에 도달해 알림을 요청하면 Capture Log에 새로운 줄이 나타납니다. 필요한 경우 Capture Log Filter 대화창에서 Markers Notification Data 체크 상자를 선택 해제하면 이러한 알림들을 걸러낼 수 있습니다.

참고
통합 세부 사항 - Event
Defines the parameters of a marker.
Definition: AkAudioMarker.h:16
const char * strLabel
Label of the marker (null-terminated)
Definition: AkCallback.h:119
AkUInt32 dwIdentifier
Identifier.
Definition: AkAudioMarker.h:17
AkUInt64 AkGameObjectID
Game object ID
Definition: AkTypes.h:142
AKRESULT
Standard function call result.
Definition: AkTypes.h:213
AkUInt32 dwLabelSize
Length of label read the from the file + terminating null character.
Definition: AkAudioMarker.h:20
AkCallbackType
Type of callback. Used as a bitfield in methods AK::SoundEngine::PostEvent() and AK::SoundEngine::Dyn...
Definition: AkCallback.h:48
AKSOUNDENGINE_API AKRESULT Init(const AkCommSettings &in_settings)
#define NULL
Definition: AkTypes.h:46
@ AK_Success
The operation was successful.
Definition: AkTypes.h:215
AKSOUNDENGINE_API void Term()
AkUInt32 uIdentifier
Cue point identifier
Definition: AkCallback.h:117
AkUInt32 AkUniqueID
Unique 32-bit ID
Definition: AkTypes.h:134
AkUInt32 uLabelSize
Size of the label string (including the terminating null character)
Definition: AkCallback.h:120
AkUInt32 uPosition
Position in the cue point (unit: sample frames)
Definition: AkCallback.h:118
void(* AkCallbackFunc)(AkCallbackType in_eType, AkCallbackInfo *in_pCallbackInfo)
Definition: AkCallback.h:266
const char * strLabel
Label of the marker taken from the file.
Definition: AkAudioMarker.h:19
#define AK_GET_PLUGIN_SERVICE_MARKERS(plugin_ctx)
Definition: IAkPlugin.h:1756
uint32_t AkUInt32
Unsigned 32-bit integer
AkUInt32 dwPosition
Position in the audio data in sample frames.
Definition: AkAudioMarker.h:18
AKSOUNDENGINE_API AkPlayingID PostEvent(AkUniqueID in_eventID, AkGameObjectID in_gameObjectID, AkUInt32 in_uFlags=0, AkCallbackFunc in_pfnCallback=NULL, void *in_pCookie=NULL, AkUInt32 in_cExternals=0, AkExternalSourceInfo *in_pExternalSources=NULL, AkPlayingID in_PlayingID=AK_INVALID_PLAYING_ID)
Defines the parameters of an audio buffer format.
Definition: AkCommonDefs.h:63
AkUInt32 AkPlayingID
Playing ID
Definition: AkTypes.h:137
AkForceInline AkUInt16 MaxFrames() const
Definition: AkCommonDefs.h:643

이 페이지가 도움이 되었나요?

지원이 필요하신가요?

질문이 있으신가요? 문제를 겪고 계신가요? 더 많은 정보가 필요하신가요? 저희에게 문의해주시면 도와드리겠습니다!

지원 페이지를 방문해 주세요

작업하는 프로젝트에 대해 알려주세요. 언제든지 도와드릴 준비가 되어 있습니다.

프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.

Wwise를 시작해 보세요