CRI ADX  Last Updated: 2024-07-17 10:48 p
播放数据的步骤


播放所需的文件

需要工具输出的以下文件。


  • ACF文件(*.acf)
  • ACB文件(*.acb)
  • AWB文件(*.awb)
  • 同时输出的头文件(*.h)
下面使用用于教程程序的数据。


使用的数据
  * CRIWARE

  \ * SDK

    \ * common

      o * smpdata

      \ * criatomex

        o * SampleProject.acf

        o * AtomCueSheet.acb

        \ * AtomCueSheet.h

 

 

 

: 教程程序

 

: ACF文件

: ACB文件

: ACB头文件

 


项目文件和源代码

教程的项目文件和源代码放在以下位置。


教程源代码的位置
  * CRIWARE


SDK

+- pc [平台专用]

+- tutorials : 教程程序

+- criatomex

+- playback_cue : Cue播放的教程

+- pcvc : 项目文件文件夹

| +- playback_cue.sln : Visual Studio 解决方案文件

| +- playback_cue.vcxproj : Visual Studio 项目文件

| +- playback_cue.vcxproj.filter : Visual Studio 滤波器文件

+- playback_cue.c : Cue播放的教程

 


程序的流程

程序的流程如下。
  1. 包含头文件
  2. CRI Atom运行时库的初始化处理。
  3. 必要的文件的加载
  4. 创建Voice池的创建
  5. AtomExPlayer的创建
  6. 开始播放
  7. 等待播放结束和内部状态的更新
  8. 结束处理
  9. 播放的确认
/* CRI SDK 头文件 */
#include <cri_xpt.h>
/* CRI ADX 头文件 */
#include <cri_atom_ex.h>
#include <cri_atom_wasapi.h>
/* 教程中使用的ACB文件的头文件 */
#include "AtomCueSheet.h" /* #define CRI_ATOMCUESHEET_BOMB2 (3) */
/* 样本中使用的文件名 */
#define ACF_FILE SampleProject.acf
#define ACB_FILE AtomCueSheet.acb
/* 用于教程的错误回调函数 */
static void tutorial_error_callback_func(
const CriChar8 *errid, CriUint32 p1, CriUint32 p2, CriUint32 *parray);
/* main函数 */
Sint32 main(Sint32 argc, Char8 *argv[])
{
/* 最低限度的初始化 */
tutorial_initialize();
/* 错误回调函数的注册 */
criErr_SetCallback(tutorial_error_callback_func);
/* 内存分配函数的注册 */
criAtomEx_SetUserAllocator(tutorial_alloc, tutorial_free, NULL);
/* 初始化程序时库 */
/* ACF文件的读取和注册 */
criAtomEx_RegisterAcfFile(NULL, ACF_FILE, NULL, 0);
/* 读取ACB文件,创建ACB句柄 */
acb_hn = criAtomExAcb_LoadAcbFile(NULL, ACB_FILE, NULL, NULL, NULL, 0);
/* Voice池的创建 */
/* Player的创建 */
player = criAtomExPlayer_Create(NULL, NULL, 0);
/* Cue ID的指定 */
criAtomExPlayer_SetCueId(player, acb_hn, CRI_ATOMCUESHEET_BOMB2);
/* 开始播放 */
for(;;) {
CriAtomExPlayerStatus explayer_status;
tutorial_sleep(10);
/* Server处理的执行 */
/* ExPlayer的状态确认 */
explayer_status = criAtomExPlayer_GetStatus(player);
/* 播放结束时退出循环 */
if (explayer_status == CRIATOMEXPLAYER_STATUS_PLAYEND) {
break;
}
}
/* Atom句柄的丢弃 */
/* Voice池的丢弃 */
/* Atom句柄的丢弃 */
/* ACF文件的取消注册 */
/* 结束程序库 */
/* 最小限度的结束处理*/
tutorial_finalize();
return 0;
}
void criAtomExPlayer_Destroy(CriAtomExPlayerHn player)
Destroy an AtomEx player
CriAtomExAcbObj * CriAtomExAcbHn
ACB handle
Definition: cri_le_atom_ex.h:3033
CriAtomExAcbHn criAtomExAcb_LoadAcbFile(CriFsBinderHn acb_binder, const CriChar8 *acb_path, CriFsBinderHn awb_binder, const CriChar8 *awb_path, void *work, CriSint32 work_size)
Load an ACB file
void criAtomExAcb_Release(CriAtomExAcbHn acb_hn)
Release an ACB handle
void criAtomEx_UnregisterAcf(void)
Unregister an ACF file
void criAtomEx_ExecuteMain(void)
Execute the server processing
CriBool criAtomEx_RegisterAcfFile(CriFsBinderHn binder, const CriChar8 *path, void *work, CriSint32 work_size)
Register an ACF file
#define criAtomEx_SetUserAllocator(p_malloc_func, p_free_func, p_obj)
Register a custom memory allocator
Definition: cri_le_atom_ex.h:309
CriAtomExPlayerStatus criAtomExPlayer_GetStatus(CriAtomExPlayerHn player)
Get the player status
CriAtomExPlaybackId criAtomExPlayer_Start(CriAtomExPlayerHn player)
Start the playback
CriAtomExPlayerObj * CriAtomExPlayerHn
Player handle
Definition: cri_le_atom_ex.h:3622
CriAtomExPlayerHn criAtomExPlayer_Create(const CriAtomExPlayerConfig *config, void *work, CriSint32 work_size)
Create an AtomEx player
void criAtomExPlayer_SetCueId(CriAtomExPlayerHn player, CriAtomExAcbHn acb_hn, CriAtomExCueId id)
Set the sound data to play (specifying a Cue ID)
enum CriAtomExPlayerStatusTag CriAtomExPlayerStatus
Player status
@ CRIATOMEXPLAYER_STATUS_PLAYEND
Definition: cri_le_atom_ex.h:3670
CriAtomExVoicePoolHn criAtomExVoicePool_AllocateStandardVoicePool(const CriAtomExStandardVoicePoolConfig *config, void *work, CriSint32 work_size)
Create a standard Voice Pool
struct CriAtomExVoicePoolTag * CriAtomExVoicePoolHn
Voice Pool handle
Definition: cri_le_atom_ex.h:3220
void criAtomExVoicePool_Free(CriAtomExVoicePoolHn pool)
Destroy a Voice Pool
void criAtomEx_Initialize_WASAPI(const CriAtomExConfig_WASAPI *config, void *work, CriSint32 work_size)
Library initialization
void criAtomEx_Finalize_WASAPI(void)
Finalize the library
void criErr_SetCallback(CriErrCbFunc cbf)
Register error callback function


程序说明

以下介绍各项处理的细节。


(1) 包含头文件


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
/* CRI SDK 头文件 */
#include <cri_xpt.h>
/* CRI ADX 头文件 */
#include <cri_atom_ex.h>
#include <cri_atom_wasapi.h>
/*用于教程使用的ACB文件的头文件 */
#include "../../../../common/smpdata/criatomex/AtomCueSheet.h"


由于cri_xpt.h描述了CRI独有的类型定义等,因此最先包含此文件。
至于其他头文件,则与包含顺序无关。
cri_atom_ex.h是声明使用CRI Atom功能的API的头文件。
请必须包含这些头文件。
cri_atom_wasapi.h是声明使用WASAPI音频输出功能的API的头文件。
执行为输出WASAPI音频而准备的API(机型个别的初始化/结束函数等)时必须包含此文件。
AtomCueSheet.h是描述ACB文件、AWB文件的Cue信息的头文件。
要播放的Cue ID在此头文件中被定义为常量宏。
(如果不使用宏而是直接指定Cue名和Cue ID时,则不需要包含此头文件。)

(2)初始化CRI Atom运行库


/* 错误回调函数的注册 */
criErr_SetCallback(tutorial_error_callback_func);
/* 内存分配函数的注册 */
criAtomEx_SetUserAllocator(tutorial_alloc, tutorial_free, NULL);
/* 初始化程序库 */


初始化CRI Atom程序时库。 在本教程中,简化了为 criAtomEx_Initialize_WASAPI 函数指定的参数。 criAtomEx_Initialize_WASAPI 函数的第一个参数是初始化参数,如果指定为NULL,则使用预设设置执行初始化。 criAtomEx_Initialize_WASAPI 函数的第二、第三个参数是指定初始化所需的工作区的参数。 使用 criAtomEx_SetUserAllocator 函数设置内存分配函数, 如果为工作区的指针指定NULL,为工作区大小指定0,则在 criAtomEx_Initialize_WASAPI 函数内部动态分配工作区。


(3) 必要的文件的加载


/* ACF文件的读取和注册 */
criAtomEx_RegisterAcfFile(NULL, PATH ACF_FILE, NULL, 0);
/* 读取ACB文件,创建ACB句柄 */
NULL, PATH ACB_FILE, NULL, PATH AWB_FILE, NULL, 0);


使用 criAtomEx_RegisterAcfFile 函数,在运行时读取ACF文件。 该文件是环境设置文件。 接下来,使用 criAtomExAcb_LoadAcbFile 函数读取ACB文件并创建句柄。 在Cue播放时为Player指定ACB句柄。
两个函数都使用指定工作区大小的参数,本教程为了简化,分别指定为NULL和0。 通过指定NULL和0,在函数内部动态分配工作区。


criAtomEx_RegisterAcfFile 函数、 criAtomExAcb_LoadAcbFile 函数是同步函数。 执行 criAtomExAcb_LoadAcbFile 函数后,ACB文件加载完成, 如果函数成功,则返回有效的ACB句柄( ::CriAtomExAcbHn )。


本教程省略了错误处理,但 criAtomEx_RegisterAcfFile 函数、 criAtomExAcb_LoadAcbFile 函数可能会因为“找不到文件”等原因而失败, 建议检查返回值。


(4) Voice池的创建


/* Voice池的创建 */


创建标准Voice池。
本教程中将省略第一个参数是Voice池的创建参数。
省略时,会使用预设值创建Voice池。
由于创建的Voice池在系统端注册,播放Cue时将自动分配给Player。
本教程中未指定工作内存。
如果未在 criAtomExVoicePool_AllocateStandardVoicePool 函数中指定工作内存(指定NULL和Size 0),则会在函数内部动态分配内存。

(5) AtomExPlayer的创建


/* Player的创建 */
player = criAtomExPlayer_Create(NULL, NULL, 0);


创建AtomExPlayer(以下简称为Player。)。
本教程中将省略第一参数是创建参数。省略时,会使用预设值创建Player。 创建Player后,将获得Player句柄( ::CriAtomExPlayerHn )。 通过该Player句柄执行对Player的各种操作。
本教程中未指定工作内存。 如果未在 criAtomExPlayer_Create 函数中指定工作内存(指定NULL和Size 0), 则会在函数内部动态分配内存。


(6) 开始播放


/* Cue ID的指定 */
criAtomExPlayer_SetCueId(player, acb_hn, CRI_ATOMCUESHEET_BOMB2);
/* 开始播放 */


criAtomExPlayer_SetCueId 函数指定要播放的Cue,用 criAtomExPlayer_Start 函数开始播放。 在 criAtomExPlayer_SetCueId 函数的第二个参数中指定已加载的ACB句柄。 在第三个参数中用ID(整数值)指定ACB中的Cue。
Player会根据指定的ACB句柄和Cue ID播放ACB中的Cue数据。 本教程中指定的CRI_ATOMCUESHEET_BOMB2由AtomCueSheet.h定义。
使用 criAtomExPlayer_Start 函数开始播放。 指定用 criAtomExPlayer_Create 函数创建的AtomPlayer句柄。


(7) 等待播放结束和内部状态的更新


/* 播放循环 */
for(;;) {
CriAtomExPlayerStatus explayer_status;
tutorial_sleep(10);
/* 执行Server处理 */
/* ExPlayer的状态确认 */
explayer_status = criAtomExPlayer_GetStatus(player);
/* 播放结束时退出循环 */
if (explayer_status == CRIATOMEXPLAYER_STATUS_PLAYEND) {
break;
}
}


使用 criAtomExPlayer_GetStatus 函数获取Player的状态, 如果到达结束状态( ::CRIATOMEXPLAYER_STATUS_PLAYEND )则退出播放循环。 在播放循环中,每V调用作为CRI Atom的Server处理函数的 criAtomEx_ExecuteMain 函数。 如果没有每V调用,则无法及时读取音频数据,导致声音中断。


此外,由于需要通过CRI Atom的Server处理更新Player的状态,注意不要忘记调用 criAtomEx_ExecuteMain 函数。


(8) 结束处理


/* Atom句柄的丢弃 */
/* Voice池的丢弃 */
/* ACB句柄的丢弃 */
/* ACF文件的读取和注册 */
/* 结束程序库 */
/* 最小限度的结束处理*/
tutorial_finalize();


在应用程序结束时,将通过对应的函数丢弃各句柄。 然后在相应的句柄丢弃函数中,释放创建句柄时动态分配的工作区。 最后使用 criAtomEx_Finalize_WASAPI 函数执行程序库结束处理。


(9) 确认播放


通过上述作业,您是否能成功播放Cue? 如果能够顺利播放,则应响起爆炸声。