- CRI Atomライブラリのいくつかの関数は、実行時に作業用のメモリ領域(ワークメモリ)を必要とするものがあります。
本項では、ワークメモリの用途や、ワークメモリの割り当て方法について説明します。
ワークメモリが必要な処理
- ワークメモリを必要とする処理には、以下のものがあります。
- ライブラリの初期化
- ボイスプールの作成
- ACFファイルの読み込み
- ACBファイルの読み込み
- D-BASの作成
- AtomExプレーヤの作成
- 各処理の詳細は以下のとおりです。
(1) ライブラリの初期化
- CRI Atomライブラリは、初期化時にスレッドの作成等を行うため、ワークメモリを必要とします。
初期化時に必要なワークメモリのサイズは、 criAtomEx_CalculateWorkSize 関数で計算が可能です。
- ライブラリが初期化時に必要とするワークメモリのサイズは、初期化時に指定するフレームワーク等の設定( CriAtomExConfig )によって変化します。
例えば、スレッドモデルが 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) ボイスプールの作成
- ボイスプールを作成する際には、データ読み込み用のバッファや音声データのデコードに使用する作業領域、サウンド出力用のリソース等を確保するため、ワークメモリが必要になります。
ボイスプール作成時に必要なワークメモリのサイズは、ボイスプレーヤを作成する関数によって異なります。
- ボイスプール作成関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
- ライブラリの初期化と同様、ボイスプールの作成時に必要なワークメモリのサイズは、ボイスプール作成時の設定( CriAtomExAdxVoicePoolConfig 等)によって変化します。
具体的には、最大出力チャンネル数や最大サンプリング周波数については、指定する値が小さいほど必要とするワークメモリは小さくなります。
例えば、ボイスプールでモノラル音声しか再生しない場合、最大出力チャンネル数を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作成関数とワークメモリサイズ計算関数
D-BAS作成関数 | ワークメモリ計算関数 |
::criAtomExDbas_Create | ::criAtomExDbas_CalculateWorkSize |
- D-BASに設定する消費ビットレートを求める際は、以下の関数を使用します。
-
- 各機種固有のコーデックが存在する場合、上記と同様の関数が機種固有ヘッダーで宣言されています。
(6) AtomExプレーヤの作成
- AtomExプレーヤを作成する際には、プレーヤ領域や、ファイルパスを保存する領域を確保するため、ワークメモリが必要になります。
AtomExプレーヤ作成時に必要なワークメモリのサイズは、ファイルパス指定の再生を行うかどうかにより異なります。
- AtomExプレーヤ作成関数と、ワークメモリサイズ計算関数の対応付けは、以下のとおりです。
ワークメモリの割り当て方法
- 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方式によるワークメモリの割り当て手順は以下のようになります。
- ワークメモリ要求関数(※)に必要なワークメモリのサイズを計算する。
- 計算結果として返されたサイズ分のメモリを確保する。
- 確保されたメモリを引数とし、ワークメモリ要求関数を実行する。
- ※ワークメモリ要求関数:関数実行時にワークメモリを必要とする関数。
- [例]
Fixed Memory方式を用いて初期化処理を行う例を、以下に示します。
main()
{
void *work;
CriSint32 size;
:
work = malloc((size_t)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ライブラリが規定するインターフェースに合わせて実装し、登録する必要があります。
具体的なインターフェースと登録関数は以下のとおりです。
- メモリ確保関数とメモリ解放関数をCRI Atomライブラリにセットすることで、CRI Atomライブラリはワークメモリの確保/解放を全て登録された関数経由で行うよう動作を変更します。
そのため、User Allocator方式を用いる場合、ワークメモリ要求関数を実行する際でもワークメモリを関数に指定する必要はありません。
(メモリアドレスに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()
{
:
:
:
}
#define criAtomEx_SetUserAllocator(p_malloc_func, p_free_func, p_obj)
ユーザアロケーターの登録
Definition: cri_le_atom_ex.h:313