CRI ADX  Last Updated: 2024-07-17 10:47 p
Procedure for Data Playback


Files needed for playback

The following files, which are output by the tool, are needed:


  • ACF file (.*acf)
  • ACB file (.*acb)
  • AWB file (*.awb)
  • Header files output with these files (*.h)
Data for tutorial programs is used here.


Data to use
  * CRIWARE

  \ * SDK

    \ * common

      \ * smpdata

        \ * criatomex

          o * SampleProject.acf

          o * AtomCueSheet.acb

          \ * AtomCueSheet.h

 

 

 

: Tutorial programs

 

: ACF file

: ACB file

: ACB header file

 


Project File and Source Code

The project file and source code are located in the following folders.
Location of Tutorial source code
  * CRIWARE

  \ * SDK

    \ * pc

      \ * tutorials

        \ * criatomex

          \ * playback_cue

            o * pcvc

            | o * playback_cue.sln

            | o * playback_cue.vcxproj

            | \ * playback_cue.vcxproj.filter

            |  

            \ * playback_cue.c

 

 

[Platform-specific]

: Tutorial programs

 

: Cue playback tutorial

: Project file folder

: Visual Studio solution file

: Visual Studio project file

: Visual Studio filter file

 

: Cue playback tutorial program

 


Program Flow

The program flow is as follows:
/* CRI SDK header files */
#include <cri_xpt.h>
/* CRI ADX header files */
#include <cri_atom_ex.h>
#include <cri_atom_wasapi.h>
/* Header for the ACB file used in this tutorial */
#include "AtomCueSheet.h" /* #define CRI_ATOMCUESHEET_BOMB2 (3) */
/* File names for this tutorial */
#define ACF_FILE "SampleProject.acf"
#define ACB_FILE "AtomCueSheet.acb"
/* The error callback function for this tutorial */
static void tutorial_error_callback_func(
const CriChar8 *errid, CriUint32 p1, CriUint32 p2, CriUint32 *parray);
/* main function */
Sint32 main(Sint32 argc, Char8 *argv[])
{
/* Initialization (minimum) */
tutorial_initialize();
/* Registering the error callback function */
criErr_SetCallback(tutorial_error_callback_func);
/* Registering the memory allocator */
criAtomEx_SetUserAllocator(tutorial_alloc, tutorial_free, NULL);
/* Initializing the library */
criAtomEx_Initialize_PC(NULL, NULL, 0);
/* Reading and registering the ACF file */
criAtomEx_RegisterAcfFile(NULL, ACF_FILE, NULL, 0);
/* Reading the ACB file and creating the ACB handle */
acb_hn = criAtomExAcb_LoadAcbFile(NULL, ACB_FILE, NULL, NULL, NULL, 0);
/* Creating a Voice Pool */
/* Creating a player */
player = criAtomExPlayer_Create(NULL, NULL, 0);
/* Specifying a Cue ID */
criAtomExPlayer_SetCueId(player, acb_hn, CRI_ATOMCUESHEET_BOMB2);
/* Starting the playback */
for(;;) {
CriAtomExPlayerStatus explayer_status;
tutorial_sleep(10);
/* Executing the server process */
/* Checking the ExPlayer status */
explayer_status = criAtomExPlayer_GetStatus(player);
/* Exiting the playback loop if the status is PLAYEND */
if (explayer_status == CRIATOMEXPLAYER_STATUS_PLAYEND) {
break;
}
}
/* Discarding the Atom handle */
/* Discarding the voice pool */
/* Discarding the ACB handle */
/* Unregistering the ACF file */
/* Terminating the library */
/* Finalization (minimum) */
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_PC(const CriAtomExConfig_PC *config, void *work, CriSint32 work_size)
Initialize the library.
void criAtomEx_Finalize_WASAPI(void)
Finalize the library.
void criErr_SetCallback(CriErrCbFunc cbf)
Register error callback function.

Description of the Program

Detailed explanation for each step.

(1) Including the header files

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
/* CRI SDK header file */
#include <cri_xpt.h>
/* CRI ADX header files */
#include <cri_atom_ex.h>
#include <cri_atom_wasapi.h>
/* Header for the ACB file used in this tutorial */
#include "../../../../common/smpdata/criatomex/AtomCueSheet.h"

Include cri_xpt.h first, as it contains CRI-specific type definitions.
Other header files have no restriction for their order.
cri_atom_ex.h contains the API declarations for the functions of CRI Atom.
Therefore, be sure to include it.
cri_atom_wasapi.h contains the API declarations for the functions of the WASAPI audio outputs.
Be sure to include it to execute specific APIs for WASAPI audio outputs (e.g., target specific initialization / finalization).
AtomCueSheet.h contains Cue information related to the ACB and AWB files used.
Cue IDs used for the playback are defined in this header file.
(When directly specifying a Cue name or a Cue ID without using a macro, this header file is not required.)
(2) Initializing the CRI Atom library

/* Registering the error callback function */
criErr_SetCallback(tutorial_error_callback_func);
/* Registering the memory allocator */
criAtomEx_SetUserAllocator(tutorial_alloc, tutorial_free, NULL);
/* Initializing the library */
void criAtomEx_Initialize_WASAPI(const CriAtomExConfig_WASAPI *config, void *work, CriSint32 work_size)
Library initialization.

Initializing the CRI Atom Library.
To make this tutorial easier to understand, we pass simplified parameters to the criAtomEx_Initialize_WASAPI function.
We set the first parameter - which represents the initialization settings - to NULL, which means that the default settings will be used.
The second and the third parameters are for the specification of the working area (memory buffer).
In fact, the criAtomEx_Initialize_WASAPI function will allocate its working memory dynamically and internally if a memory allocator function was set via a call to the criAtomEx_SetUserAllocator function, and NULL is passed as the working area pointer (second parameter), with a working memory size of 0 (third parameter).


(3) Loading necessary files

/* Reading and registering the ACF file */
criAtomEx_RegisterAcfFile(NULL, PATH ACF_FILE, NULL, 0);
/* Reading the ACB file and creating the ACB handle */
NULL, PATH ACB_FILE, NULL, PATH AWB_FILE, NULL, 0);

Use the criAtomEx_RegisterAcfFile function to load the ACF file which is used to configure the runtime environment.
Then, calling the criAtomExAcb_LoadAcbFile function to read the ACB file and creates an ACB handle.
The ACB handle is specified to the player during the Cue playback.
Both functions provide parameters to specify a working memory area, but to simplify this tutorial, NULL and 0 are specified for the location and size respectively.
By doing so, the function allocates its working memory dynamically and internally.


Both the criAtomEx_RegisterAcfFile and the criAtomExAcb_LoadAcbFile functions are synchronous.
Once the criAtomExAcb_LoadAcbFile function is successfully executed, ACB file loading should be completed and a valid ACB handle( ::CriAtomExAcbHn ) should be returned.


Error handling is ignored in this tutorial but we recommend you to check the return values of both the criAtomEx_RegisterAcfFile and criAtomExAcb_LoadAcbFile functions as they may fail due to reasons like "file not found".


(4) Allocating a voice pool

/* Allocating a voice pool */

This code shows how to allocate the default voice pool.
The first argument is a structure of parameters used for the voice pool allocation, but in this tutorial NULL is passed instead.
In this case, the voice pool is allocated using the default parameters.
Once the voice pool is allocated, it is automatically assigned to the Player for the playback of Cues.
In this tutorial, the working memory area is not specified either.
When calling the criAtomExVoicePool_AllocateStandardVoicePool function with NULL and 0 for the location and size of the area, it is allocated dynamically instead.

(5) Creating an AtomExPlayer

/* Creating a player */
player = criAtomExPlayer_Create(NULL, NULL, 0);

This code creates an AtomExPlayer (we refer to it simply as 'player' here).
Again, arguments are NULL and 0 to request the use of the default settings and the function returns a player handle (CriAtomExPlayerHn).
The AtomExPlayer can be controlled through this handle (e.g., its volume can be changed).
In this tutorial, the working area is not specified.
When not specified (by calling the criAtomExPlayer_Create function with NULL and 0), the working area is allocated dynamically.


(6) Starting the playback

/* Specifying a Cue ID */
criAtomExPlayer_SetCueId(player, acb_hn, CRI_ATOMCUESHEET_BOMB2);
/* Starting the playback */

After specifying a Cue with the criAtomExPlayer_SetCueId function, the playback can be started by calling the criAtomExPlayer_Start function.
The second argument of the function is the ACB handle which refers to a previously loaded ACB file and the third argument is the ID (number) of Cue in the ACB.
The player plays the Cue data specified by the ACB handle and the Cue ID.
The ID ( CRI_ATOMCUESHEET_BOMB2 ) used in this tutorial (CRI_TUTORIAL_BOMB2) is defined in the AtomCueSheet.h header.
To start playing back a sound, call the criAtomExPlayer_Start function with the Atom player handle returned by the criAtomExPlayer_Create function.


(7) Waiting for the end of the playback and updates to the internal state

/* Playback loop */
for(;;) {
CriAtomExPlayerStatus explayer_status;
tutorial_sleep(10);
/* Executing the server process */
/* Checking the status of the ExPlayer */
explayer_status = criAtomExPlayer_GetStatus(player);
/* Exiting the playback loop if the status is PLAYEND */
if (explayer_status == CRIATOMEXPLAYER_STATUS_PLAYEND) {
break;
}
}

The criAtomExPlayer_GetStatus function returns the player status, and if it is PLAYEND (CRIATOMEXPLAYER_STATUS_PLAYEND) then the loop is exited.
In the playback loop, the criAtomEx_ExecuteMain function, the server process of CRI Atom, should be called for every V-sync, otherwise reading sound data may be delayed, which may result in audio playback stuttering.


Moreover, as the status of the player is updated by the CRI Atom server process, please be sure to call the criAtomEx_ExecuteMain function to update the status.


(8) Finalization

/* Discarding the Atom handle */
/* Discarding the voice pool */
/* Discarding the ACB handle */
/* Unregistering the ACF */
/* Terminating the library */
/* Finalization (minimum) */
tutorial_finalize();

When terminating the application, all the handles must be destroyed by calling their respective release functions.
The work areas dynamically allocated when creating the handles are also released at that time.
Finally, call the criAtomEx_Finalize_WASAPI function to terminate the process of the library.


(9) Verifying the playback

Did you check the Cue was indeed being played back?
If you followed the steps above carefully, you should be able to hear the sound of the Cue specified on your device.