CRI ADX  Last Updated: 2024-07-17 10:48 p
Cue Playback (Memory)
This tutorial shows how to play a cue by CRI Atom.

Files Needed For Playback

The files required for playback cues are ACF file (*.acf), ACB file (*.acb), AWB file (*.awb) and header files (*.h).
Those files are output of the Atom tool. For this tutorial, you can use the same data as the sample program and they are located:

Files related to this tutorial
  * CRIWARE

  \ * SDK

    \ * common

      \ * smpdata

        \ * criatomex

          o * TutorialProject.acf

          o * tutorial.acb

          \ * tutorial.h

 

 

 

: Sample data for tutorial

 

: ACF file

: ACB file

: ACB header file

 

Project File and Source Code

The project file and source codes are located at 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.filters

            |  

            \ * playback_cue.c

 

 

[Platform specific]

: Tutorial program

 

: Cue playback tutorial

: Project file folder

: Visual Studio solution file

: Visual Studio project

: Visual Studio filter file

 

: Source code of Cue playback

 

Program Flow

Program flow is as follows:

  1. Include header files
  2. CRI Atom library initialization
  3. Load necessary files
  4. Allocate voice pool
  5. Create AtomEx player
  6. Start playback
  7. Wait for playend and update internal state
  8. Finalization
  9. Verify playback
/* CRI SDK Header */
#include <cri_xpt.h>
/* CRI ADX Headers */
#include <cri_atom_ex.h>
#include <cri_atom_pc.h>
/* Header file for ACB file used in this tutorial */
#include "../../../../common/smpdata/criatomex/tutorial.h"
/* Path string for data directory */
#define PATH "..\\..\\..\\..\\..\\common\\smpdata\\criatomex\\"
/* File names for the sample */
#define ACF_FILE "TutorialProject.acf"
#define ACB_FILE "tutorial.acb"
/* main function */
CriSint32 main(CriSint32 argc, CriChar8 *argv[])
{
UNUSED(argc);
UNUSED(argv);
/* Initialization (minimum) */
tutorial_initialize();
/* Registration of error callback function */
criErr_SetCallback(tutorial_error_callback_func);
/* Registration of memory allocator */
criAtomEx_SetUserAllocator(tutorial_alloc, tutorial_free, NULL);
/* Library initialization */
criAtomEx_Initialize_PC(NULL, NULL, 0);
/* Read and register ACF file */
criAtomEx_RegisterAcfFile(NULL, PATH ACF_FILE, NULL, 0);
/* Read ACB file and create ACB handle */
acb_hn = criAtomExAcb_LoadAcbFile(NULL, PATH ACB_FILE, NULL, NULL, NULL, 0);
/* Allocate voice pool */
voice_pool = criAtomExVoicePool_AllocateStandardVoicePool(NULL, NULL, 0);
/* Create player */
player = criAtomExPlayer_Create(NULL, NULL, 0);
/* Specity Cue ID */
criAtomExPlayer_SetCueId(player, acb_hn, CRI_TUTORIAL_BOMB2);
/* Start playback */
for(;;) {
CriAtomExPlayerStatus explayer_status;
tutorial_sleep(10);
/* Execute server process */
/* check the player status */
explayer_status = criAtomExPlayer_GetStatus(player);
/* Exit playback loop if the status is PLAYEND */
if (explayer_status == CRIATOMEXPLAYER_STATUS_PLAYEND) {
break;
}
}
/* Destroy player handle */
/* Free voice pool */
/* Release ACB handle */
/* Unregister ACF */
/* Library Finalization */
/* 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_Finalize_PC(void)
Finalize the library
void criAtomEx_Initialize_PC(const CriAtomExConfig_PC *config, void *work, CriSint32 work_size)
Initialize the library
void criErr_SetCallback(CriErrCbFunc cbf)
Register error callback function


Description of Program

Detail explanation for each step.

1. Include header files
/* CRI SDK Header */
#include <cri_xpt.h>
/* CRI ADX Headers */
#include <cri_atom_ex.h>
#include <cri_atom_pc.h>
/* Header file for ACB file used in this tutorial */
#include "../../../../common/smpdata/criatomex/tutorial.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 API declaration of functions for CRI Atom.
It must be included.

toturial.h contains cue information for ACB file and AWB file. Cue IDs for playback are defined in this header file.

2. CRI Atom library initialization
/* Registration of error callback */
criErr_SetCallback(tutorial_error_callback_func);
/* Registration of memory allocator */
criAtomEx_SetUserAllocator(tutorial_alloc, tutorial_free, NULL);
/* Initialization of library */
criAtomEx_Initialize_PC(NULL, NULL, 0);



Initialize CRI Atom Library.
In this tutorial, parameters for criAtomEx_Initialize_PC function are simplified.
The first argument of criAtomEx_Initialize_PC function is initialization parameter, but when it is NULL, the default setting is selected.
Second and third parameters are for specification of work area.
criAtomEx_Initialize_PC allocates work memory dynamically and internally when memory allocator function is set by criAtomEx_SetUserAllocator and NULL is passed as work area point and work memory size is 0 (zero).

3. Loading of necessary files
/* Read and register ACF file */
criAtomEx_RegisterAcfFile(NULL, PATH ACF_FILE, NULL, 0);
/* Read ACB file and create ACB handle */
acb_hn = criAtomExAcb_LoadAcbFile(NULL, PATH ACB_FILE, NULL, NULL, NULL, 0);



Calling criAtomEx_RegisterAcfFile function to load ACF file which is used to configurate runtime environment. Then, call criAtomExAcb_LoadAcbFile function to read ACB file.
criAtomExAcb_LoadAcbFile function returns ACB handle which will be referred by cue player.

Both functions require two arguments to specify work memory. In this tutorial NULL and 0(zero) are passed for simplification, then actual work memory area are allocated dynamically.
Both criAtomEx_RegisterAcfFile and criAtomExAcb_LoadAcbFile are synchronous functions.
After criAtomExAcb_LoadAcbFile successfully executed, ACB file loading should be completed and a valid ACB handle ( CriAtomExAcbHn ) should be returned.

Error handling is eliminated in this tutorial but return value verification should be recommended as both criAtomEx_RegisterAcfFile and criAtomExAcb_LoadAcbFile may fail with some reasons such as "file not found".

4. Allocate voice pool
/* Allocate voice pool */



This code shows how to allocate default voice pool.
The first argument is a structure of parameters such as max number of channels,max sampling rate, etc. and here NULL is passed to allocate default voice pool.
Once voice pool is allocated, it is assigned to player automatically for playback cues.
For work memory, NULL and 0(zero) are specified in this tutorial to allocate work memory dynamically.

5. Create AtomEx player
/* Create player */
player = criAtomExPlayer_Create(NULL, NULL, 0);



This code creates AtomEx player (in short we call it "player" simply here).
Again arguments are NULLs and 0 to specify default setting and the function returns a player handle (CriAtomExPlayerHn).
You can control AtomEx player through this handle.

6. Start playback
/* Specify Cue-ID */
criAtomExPlayer_SetCueId(player, acb_hn, CRI_TUTORIAL_BOMB2);
/* Start playiback */



Specifing a cue by criAtomExPlayer_SetCueId, start playback by criAtomExPlayer_Start.
The second argument of criAtomExPlayer_SetCueId should be the ACB handle which refers loaded ACB file and the third argument is ID (number) of cue in the ACB.
The player plays the cue data specified by the ACB handle and cue ID.
The ID in this tutorial, CRI_TUTORIAL_BOMB2, is defined in tutorial.h.
To start playback sound, call criAtomExPlayer_Start with Atom player handle created by criAtomExPlayer_Create.

7. Waiting for play-end and updating internal state
/* Playback loop */
for(;;) {
CriAtomExPlayerStatus explayer_status;
tutorial_sleep(10);
/* Execute server process */
/* check the status of the player */
explayer_status = criAtomExPlayer_GetStatus(player);
/* Exit playback loop if play-end */
if (explayer_status == CRIATOMEXPLAYER_STATUS_PLAYEND) {
break;
}
}


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

Also the status of player is updated by CRI Atom server process, so criAtomEx_ExecuteMain should be called for keep updating the status.

8. Finalization
/* Destroy Atom handle */
/* Free voice pool */
/* Release ACB handle */
/* Unregister ACF */
/* Finalize library */



At the termination of the application, each handles should be discarded through appropriate function, then all work area allocated dynamically are released in those functions.
Then lastly terminate the library by criAtomEx_Finalize_PC function.

9. Verify playback
Can you hear the sound of cue, can't you ?
You should hear an explosion sound now.