- CRI Atomライブラリのいくつかの関数は、実行時に作業用のメモリ領域(ワークメモリ)を必要とするものがあります。
本項では、ワークメモリの割り当て方法や、各ワークメモリの用途について説明します。
ワークメモリの割り当て方法
- CRI Atomライブラリを使用する場合、ライブラリを初期化する際や、AtomExプレーヤを作成する際に、ライブラリが使用する作業領域として"ワークメモリ"を与える必要があります。
CRI Atomライブラリに対してワークメモリを割り当てる方法として、CRI Atomライブラリは以下2通りの方法を提供しています。
- User Allocator方式:メモリアロケータをCRI Atomライブラリに登録する方法
- Fixed Memory方式:アプリケーションで用意したメモリ領域を割り当てる方法
- 基本的には、プログラムの実装がシンプルになる「User Allocator方式」を推奨します。
- 各方式の詳細は以下のとおりです。
(1) User Allocator方式について
- User Allocator方式とは、アプリケーションがメモリ確保/解放のための関数をライブラリに登録するだけで、細かなメモリ割り当てを制御しない方式です。
CRI Atomライブラリはワークメモリが必要な時に、登録された関数を使って必要なサイズのメモリを確保します。
プログラム側のメモリ管理がシンプルになるのが最大のメリットです。
本SDKのサンプルプログラムは全て User Allocator方式で実装してあります。
- メモリ確保関数は標準ライブラリのmalloc関数に相当するもので、指定したサイズ分のメモリを動的に確保し、メモリブロックのアドレスを返す関数です。
同様に、メモリ解放関数は標準ライブラリのfree関数に相当するもので、メモリ確保関数で確保されたメモリブロックを解放する関数です。 ユーザはこれら2つの機能を、CRI Atomライブラリが規定するインターフェースに合わせて実装し、登録する必要があります。
具体的なインターフェースと登録関数は以下のとおりです。
- メモリ確保/解放関数の登録は criAtomEx_SetUserAllocator 関数を使用します。ライブラリ初期化前に呼び出してください。
- ワークメモリを必要とする各関数を呼び出す時の引数では、メモリアドレスにNULL、メモリサイズに0を渡してください。
- 以上の手順をまとめると、User Allocator方式によるワークメモリの割り当て手順は以下のようになります。
- メモリ確保関数とメモリ解放関数をCRI Atomライブラリに登録する。
- ワークメモリ要求関数を実行時の引数で、メモリアドレスは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);
criAtomEx_Initialize_WASAPI(NULL, NULL, 0);
:
:
criAtomEx_Finalize_WASAPI();
:
}
(2) Fixed Memory方式について
- Fixed Memory方式は、必要なワークメモリをアプリケーションがあらかじめ確保してから、CRI Atomライブラリの各関数に渡す方式です。
アプリケーション全体でメモリを統一管理している場合などに向いた使用方法です。
ただし、各ワークメモリに対して「必要サイズの計算」→「ワークサイズの確保」という手順が必要になるためプログラムは複雑になります。
- criAtomEx_Initialize_WASAPI 関数や criAtomExPlayer_Create 関数等、ライブラリに対してメモリを割り当てる必要があるAPIは、関数の引数に必ず以下の2つのパラメータが含まれています。
- 例えば、 criAtomEx_Initialize_WASAPI 関数の場合、第二引数の「void *work」と、第三引数の「CriSint32 size」が上記に該当します。
- これらのAPIを実行する際には、ユーザはあらかじめ確保しておいたメモリ領域を、関数の引数としてセットする必要があります。
- 関数にセットするワークメモリのサイズは、専用のワークメモリサイズ計算関数を用いて計算します。
例えば、 criAtomEx_Initialize_WASAPI 関数の場合、関数の実行に必要なワークメモリのサイズは、 criAtomEx_CalculateWorkSize_WASAPI 関数を使って計算することが可能です。
- 以上の手順をまとめると、Fixed Memory方式によるワークメモリの割り当て手順は以下のようになります。
- ワークメモリ要求関数(※)に必要なワークメモリのサイズを計算する。
- 計算結果として返されたサイズ分のメモリを確保する。
- 確保されたメモリを引数とし、ワークメモリ要求関数を実行する。
- ※ワークメモリ要求関数:関数実行時にワークメモリを必要とする関数。
- [例]
Fixed Memory方式を用いて初期化処理を行う例を、以下に示します。
main()
{
void *work;
CriSint32 size;
:
size = criAtomEx_CalculateWorkSize(&config);
work = malloc((size_t)size);
criAtomEx_Initialize(&config, work, size);
:
:
criAtomEx_Finalize();
free(work);
:
}
- [注意]
ワークメモリとしてセットした領域は、該当のモジュールが破棄されるまで様々な用途に利用されます。
例えばライブラリ初期化で渡したワークメモリは、ライブラリ終了までアプリケーションが領域を保持し続けるよう注意してください。
(ワークメモリを他の用途に転用したり、解放しないでください。)
ワークメモリが必要な処理
- 本項の説明は Fixed Memory方式を使用するプログラム向けです。
- ワークメモリを必要とする処理には、以下のものがあります。
- ライブラリの初期化
- ボイスプールの作成
- ACFファイルの読み込み
- ACBファイルの読み込み
- D-BASの作成
- AtomExプレーヤの作成
- 各処理の詳細は以下のとおりです。
(1) ライブラリの初期化
- CRI Atomライブラリは、初期化時にスレッドの作成等を行うため、ワークメモリを必要とします。
初期化時に必要なワークメモリのサイズは、 criAtomEx_CalculateWorkSize_WASAPI 関数で計算が可能です。
ライブラリが初期化時に必要とするワークメモリのサイズは、初期化時に指定するフレームワーク等の設定( CriAtomExConfig_WASAPI )によって変化します。
- 例えば、スレッドモデルが CRIATOMEX_THREAD_MODEL_MULTI の場合、CRI Atomライブラリはスレッドを作成するため、スレッド作成用のメモリ領域を必要とします。
しかし、スレッドモデルが CRIATOMEX_THREAD_MODEL_USER_MULTI や CRIATOMEX_THREAD_MODEL_SINGLE の場合、CRI Atomライブラリはスレッドを作成しないため、スレッド作成用のメモリ領域を必要としません。
そのため、スレッドモデルに CRIATOMEX_THREAD_MODEL_MULTI を指定する場合に比べ、 CRIATOMEX_THREAD_MODEL_USER_MULTI や CRIATOMEX_THREAD_MODEL_SINGLE 指定時は必要なワークメモリのサイズが小さくなります。
- [注意]
スレッドモデルに CRIATOMEX_THREAD_MODEL_USER_MULTI や CRIATOMEX_THREAD_MODEL_SINGLE を指定した場合、必要なメモリサイズは小さくなりますが、サーバ処理の負荷が大きくなります。
( CRIATOMEX_THREAD_MODEL_MULTI 指定時に別スレッド上で行われる処理を、全てサーバ処理内で行うようになるため。)
そのため、ユーザ自身でサーバ処理の負荷変動を吸収する仕組みを実装する必要があるため、実装の難度は高くなります。
(2) ボイスプールの作成
- ボイスプールを作成する際には、データ読み込み用のバッファや音声データのデコードに使用する作業領域、サウンド出力用のリソース等を確保するため、ワークメモリが必要になります。
ボイスプール作成時に必要なワークメモリのサイズは、ボイスプールを作成する関数によって異なります。
- ボイスプール作成関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
- ライブラリの初期化と同様、ボイスプールの作成時に必要なワークメモリのサイズは、ボイスプール作成時の設定( CriAtomExStandardVoicePoolConfig 等)によって変化します。
具体的には、最大出力チャンネル数や最大サンプリング周波数については、指定する値が小さいほど必要とするワークメモリは小さくなります。
例えば、ボイスプールでモノラル音声しか再生しない場合、最大出力チャンネル数を1に指定することで、2を指定する場合に比べてワークメモリを小さく抑えることが可能です。
同様に、サンプリング周波数が24kHz以下の音声しか再生しない、最大サンプリング周波数に24000を指定することで、48000を指定する場合に比べてワークメモリを小さく押さえることが可能です。
- [注意]
最大出力チャンネル数を1に設定してボイスプールを作成した場合、作成されたボイスプールではステレオ音声を再生することはできません。
同様に、最大サンプリング周波数を24kHzに設定してボイスプールを作成した場合、作成されたボイスプールでは32kHzや48kHzの音声を再生することはできません。
(3) ACFの登録
- ACFを登録する際には、ACF情報を保存する領域やACFファイルから直接登録する場合は、データ読み込み用のバッファを確保するため、ワークメモリが必要になります。
ACF登録に必要なワークメモリのサイズは、ACFを登録する方法により異なります。
- ACF登録関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
(4) ACBのロード
- ACBをロードする際には、ACB情報を保存する領域や、ACBファイルからロードする場合はデータ読み込み用のバッファを確保するため、ワークメモリが必要になります。
ACBのロードに必要なワークメモリのサイズは、ACBのロード方法により異なります。
- ACBロード関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
(5) D-BASの作成
- D-BASはストリーミングバッファの管理機能であるため、ストリーミングバッファと、ストリーミングバッファを管理するためのワークメモリが必要です。
D-BAS作成時に必要なワークメモリのサイズは、ストリーミング再生を利用するアプリケーション単位、またはシーン単位で異なります。
-
- D-BASに設定する消費ビットレートを求める際は、以下の関数を使用します。
-
- 各機種固有のコーデックが存在する場合、上記と同様の関数が機種固有ヘッダで宣言されています。
(6) AtomExプレーヤの作成
- AtomExプレーヤを作成する際には、プレーヤ領域や、ファイルパスを保存する領域を確保するため、ワークメモリが必要になります。
AtomExプレーヤ作成時に必要なワークメモリのサイズは、ファイルパス指定の再生を行うかどうかにより異なります。
- AtomExプレーヤ作成関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。