CRI ADX  Last Updated: 2024-03-21 14:32 p
ワークメモリについて
CRI Atomライブラリのいくつかの関数は、実行時に作業用のメモリ領域(ワークメモリ)を必要とするものがあります。
本項では、ワークメモリの用途や、ワークメモリの割り当て方法について説明します。

ワークメモリが必要な処理

ワークメモリを必要とする処理には、以下のものがあります。
  • ライブラリの初期化
  • ボイスプールの作成
  • ACFファイルの読み込み
  • ACBファイルの読み込み
  • D-BASの作成
  • AtomExプレーヤの作成
各処理の詳細は以下のとおりです。

(1) ライブラリの初期化
CRI Atomライブラリは、初期化時にスレッドの作成等を行うため、ワークメモリを必要とします。
初期化時に必要なワークメモリのサイズは、 criAtomEx_CalculateWorkSize 関数で計算が可能です。
ライブラリが初期化時に必要とするワークメモリのサイズは、初期化時に指定するフレームワーク等の設定( CriAtomExConfig )によって変化します。
例えば、スレッドモデルが CRIATOMEX_THREAD_MODEL_MULTI の場合、CRI Atomライブラリはスレッドを作成するため、スレッド作成用のメモリ領域を必要とします。
しかし、スレッドモデルが CRIATOMEX_THREAD_MODEL_USER_MULTICRIATOMEX_THREAD_MODEL_SINGLE の場合、CRI Atomライブラリはスレッドを作成しないため、スレッド作成用のメモリ領域を必要としません。
そのため、スレッドモデルに CRIATOMEX_THREAD_MODEL_MULTI を指定する場合に比べ、 CRIATOMEX_THREAD_MODEL_USER_MULTICRIATOMEX_THREAD_MODEL_SINGLE 指定時は必要なワークメモリのサイズが小さくなります。
[注意]
スレッドモデルに CRIATOMEX_THREAD_MODEL_USER_MULTICRIATOMEX_THREAD_MODEL_SINGLE を指定した場合、必要なメモリサイズは小さくなりますが、サーバー処理の負荷が大きくなります。
CRIATOMEX_THREAD_MODEL_MULTI 指定時に別スレッド上で行われる処理を、全てサーバー処理内で行うようになるため。)
そのため、ユーザ自身でサーバー処理の負荷変動を吸収する仕組みを実装する必要があるため、実装の難度は高くなります。
(2) ボイスプールの作成
ボイスプールを作成する際には、データ読み込み用のバッファや音声データのデコードに使用する作業領域、サウンド出力用のリソース等を確保するため、ワークメモリが必要になります。
ボイスプール作成時に必要なワークメモリのサイズは、ボイスプレーヤを作成する関数によって異なります。
ボイスプール作成関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
ボイスプール作成関数とワークメモリサイズ計算関数
ボイスプール作成関数 ワークメモリ計算関数
criAtomExVoicePool_AllocateStandardVoicePool criAtomExVoicePool_CalculateWorkSizeForStandardVoicePool
criAtomExVoicePool_AllocateAdxVoicePool criAtomExVoicePool_CalculateWorkSizeForAdxVoicePool
criAtomExVoicePool_AllocateHcaVoicePool criAtomExVoicePool_CalculateWorkSizeForHcaVoicePool
criAtomExVoicePool_AllocateHcaMxVoicePool criAtomExVoicePool_CalculateWorkSizeForHcaMxVoicePool



ライブラリの初期化と同様、ボイスプールの作成時に必要なワークメモリのサイズは、ボイスプール作成時の設定( CriAtomExAdxVoicePoolConfig 等)によって変化します。
具体的には、最大出力チャンネル数や最大サンプリング周波数については、指定する値が小さいほど必要とするワークメモリは小さくなります。
例えば、ボイスプールでモノラル音声しか再生しない場合、最大出力チャンネル数を1に指定することで、2を指定する場合に比べてワークメモリを小さく抑えることが可能です。
同様に、サンプリング周波数が24kHz以下の音声しか再生しない、最大サンプリング周波数に24000を指定することで、48000を指定する場合に比べてワークメモリを小さく押さえることが可能です。
[注意]
最大出力チャンネル数を1に設定してボイスプールを作成した場合、作成されたボイスプールではステレオ音声を再生することはできません。
同様に、最大サンプリング周波数を24kHzに設定してボイスプールを作成した場合、作成されたボイスプールでは32kHzや48kHzの音声を再生することはできません。
(3) ACFファイルの読み込み
ACFを登録する際に、管理領域としてワークメモリが必要になります。
ACF登録に必要なワークメモリのサイズは、ACFを登録する方法により異なります。
  • 読み込み済みメモリ領域指定: 管理領域
  • ファイル指定: 管理領域 + データ読み込み領域
    ACF登録に必要なワークメモリのサイズは、ACFを登録する方法により異なります。
ACF登録関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
ACF登録関数とワークメモリサイズ計算関数
ACF登録関数 ワークメモリ計算関数
criAtomEx_RegisterAcfData criAtomEx_CalculateWorkSizeForRegisterAcfData
criAtomEx_RegisterAcfFile criAtomEx_CalculateWorkSizeForRegisterAcfFile


(4) ACBファイルの読み込み
ACBをロードする際に、管理領域としてワークメモリが必要になります。
ACBのロードに必要なワークメモリのサイズは、ACBをロードする方法により異なります。
  • 読み込み済みメモリ領域指定: 管理領域
  • ファイル指定: 管理領域 + データ読み込み領域
    ACBのロードに必要なワークメモリのサイズは、ACBのロード方法により異なります。
ACBロード関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
ACBロード関数とワークメモリサイズ計算関数
ACBロード関数 ワークメモリ計算関数
criAtomExAcb_LoadAcbData criAtomExAcb_CalculateWorkSizeForLoadAcbData
criAtomExAcb_LoadAcbFile criAtomExAcb_CalculateWorkSizeForLoadAcbFile


(5) D-BASの作成
D-BASはストリーミングバッファの管理機能であるため、ストリーミングバッファと、ストリーミングバッファを管理するためのワークメモリが必要です。
D-BAS作成時に必要なワークメモリのサイズは、ストリーミング再生を利用するアプリケーション単位、またはシーン単位で異なります。
D-BAS作成関数とワークメモリサイズ計算関数
D-BAS作成関数 ワークメモリ計算関数
criAtomExDbas_Create criAtomExDbas_CalculateWorkSize

D-BASに設定する消費ビットレートを求める際は、以下の関数を使用します。
各コーデックの消費ビットレート計算関数
ADX HCA(HCA-MX)
criAtomEx_CalculateAdxBitrate criAtomEx_CalculateHcaBitrate

各機種固有のコーデックが存在する場合、上記と同様の関数が機種固有ヘッダーで宣言されています。
(6) AtomExプレーヤの作成
AtomExプレーヤを作成する際には、プレーヤ領域や、ファイルパスを保存する領域を確保するため、ワークメモリが必要になります。
AtomExプレーヤ作成時に必要なワークメモリのサイズは、ファイルパス指定の再生を行うかどうかにより異なります。
AtomExプレーヤ作成関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
AtomExプレーヤ作成関数とワークメモリサイズ計算関数
AtomExプレーヤ作成関数 ワークメモリ計算関数
criAtomExPlayer_Create criAtomExPlayer_CalculateWorkSize


ワークメモリの割り当て方法

CRI Atomライブラリを使用する場合、ライブラリを初期化する際やAtomExプレーヤを作成する際に、ライブラリが使用する作業領域として"ワークメモリ"を与える必要があります。
CRI Atomライブラリに対してワークメモリを割り当てる方法として、CRI Atomライブラリは以下2通りの方法を提供しています。
  • Fixed Memory方式:アプリケーションで用意したメモリ領域を割り当てる方法
  • User Allocator方式:メモリアロケーターをCRI Atomライブラリに登録する方法
各方式の詳細は以下のとおりです。
(1) Fixed Memory方式について
Fixed Memory方式は、ワークメモリを必要とする関数を実行する際に、必要なワークメモリを関数の引数としてセットする方法です。
criAtomEx_Initialize 関数(ライブラリの初期化)や、 criAtomExPlayer_Create 関数(AtomExプレーヤの作成)等、ライブラリに対してメモリを割り当てる必要があるAPIについては、関数の引数に必ず以下の2つのパラメーターが含まれています。
  • バッファアドレス
  • バッファサイズ
例えば、 criAtomEx_Initialize 関数の場合、第二引数の「void *work」と、第三引数の「CriSint32 size」が上記に該当します。
これらのAPIを実行する際には、ユーザはあらかじめ確保しておいたメモリ領域を、関数の引数としてセットする必要があります。
関数にセットするワークメモリのサイズは、専用のワークメモリサイズ計算関数を用いて計算します。
例えば、 criAtomEx_Initialize 関数の場合、関数の実行に必要なワークメモリのサイズは、 criAtomEx_CalculateWorkSize 関数を使って計算することが可能です。
以上の手順をまとめると、Fixed Memory方式によるワークメモリの割り当て手順は以下のようになります。
  1. ワークメモリ要求関数(※)に必要なワークメモリのサイズを計算する。
  2. 計算結果として返されたサイズ分のメモリを確保する。
  3. 確保されたメモリを引数とし、ワークメモリ要求関数を実行する。
※ワークメモリ要求関数:関数実行時にワークメモリを必要とする関数。
[例]
Fixed Memory方式を用いて初期化処理を行う例を、以下に示します。
main()
{
void *work; // ワークメモリアドレス
CriSint32 size; // ワークメモリサイズ
:
// ライブラリの初期化に必要なワークメモリのサイズを計算
size = criAtomEx_CalculateWorkSize(&config);
// ワークメモリの確保
work = malloc((size_t)size);
// ライブラリの初期化
// →確保済みのワークメモリを指定する。
criAtomEx_Initialize(&config, work, size);
:
// アプリケーションのメイン処理
// →この間、確保したメモリは保持し続ける。
:
// アプリケーションを終了する際に終了処理を行う
// 必要なくなったワークメモリを解放する
free(work);
:
}
CriSint32 criAtomEx_CalculateWorkSize(const CriAtomExConfig *config)
ライブラリ初期化用ワーク領域サイズの計算
void criAtomEx_Finalize(void)
ライブラリの終了
CriBool criAtomEx_Initialize(const CriAtomExConfig *config, void *work, CriSint32 work_size)
ライブラリの初期化


[注意]
ワークメモリとしてセットした領域は、ライブラリの終了処理を行うまでの間、ライブラリ内で様々な用途に利用されます。
初期化時にセットしたワークメモリについては、終了処理を行うまでの間ユーザが保持し続ける必要があります。
(ワークメモリを他の用途に転用したり、解放しないでください。)
(2) User Allocator方式について
関数実行毎にワークメモリを割り当てる方法の他に、ユーザが作成したメモリアロケーターをCRI Atomライブラリにセットする方法があります。
この方法を、User Allocator方式と呼んでいます。
User Allocator方式を使用する場合、ユーザはあらかじめメモリ確保関数と、メモリ解放関数を用意し、CRI Atomライブラリにセットする必要があります。
メモリ確保関数は標準ライブラリのmalloc関数に相当するもので、指定したサイズ分のメモリを動的に確保し、メモリブロックのアドレスを返す関数です。
同様に、メモリ解放関数は標準ライブラリのfree関数に相当するもので、メモリ確保関数で確保されたメモリブロックを解放する関数です。 ユーザはこれら2つの機能を、CRI Atomライブラリが規定するインターフェースに合わせて実装し、登録する必要があります。
具体的なインターフェースと登録関数は以下のとおりです。
実装インターフェースと登録関数
実装インターフェース 登録関数
メモリ確保関数
CriAtomMallocFunc
criAtomEx_SetUserAllocator マクロ
メモリ解放関数
CriAtomFreeFunc
criAtomEx_SetUserAllocator マクロ



メモリ確保関数とメモリ解放関数をCRI Atomライブラリにセットすることで、CRI Atomライブラリはワークメモリの確保/解放を全て登録された関数経由で行うよう動作を変更します。
そのため、User Allocator方式を用いる場合、ワークメモリ要求関数を実行する際でもワークメモリを関数に指定する必要はありません。
(メモリアドレスにNULL、メモリサイズに0を指定します。)
以上の手順をまとめると、User Allocator方式によるワークメモリの割り当て手順は以下のようになります。
  1. メモリ確保関数とメモリ解放関数をCRI Atomライブラリに登録する。
  2. ワークメモリ要求関数を実行する。
    (メモリアドレスはNULL、メモリサイズは0を指定する。)
[例]
User Allocator方式を用いて初期化処理を行う例を、以下に示します。
// 独自のメモリ確保関数
void *user_malloc(void *obj, CriUint32 size)
{
void *mem;
// メモリの確保
mem = malloc(size);
return (mem);
}
// 独自のメモリ解放関数を用意
void user_free(void *obj, void *mem)
{
// メモリの解放
free(mem);
return;
}
main()
{
// 独自のメモリアロケーターを登録
criAtomEx_SetUserAllocator(user_malloc, user_free, NULL);
// ライブラリの初期化
// ワークメモリにはNULLと0を指定する。
// →必要なメモリは、登録したメモリ確保関数を使って確保される。
criAtomEx_Initialize(NULL, NULL, 0);
:
// アプリケーションのメイン処理
:
// アプリケーションを終了する際に終了処理を行う
// →初期化時に確保されたメモリは、登録したメモリ解放関数を使って解放される。
:
}
#define criAtomEx_SetUserAllocator(p_malloc_func, p_free_func, p_obj)
ユーザアロケーターの登録
Definition: cri_atom_ex.h:313