キュー再生(ストリーム)

本チュートリアルでは、CRI Atomを使ってキューをストリーミング再生する方法を説明します。

再生に必要なファイル

ランタイム側で必要なファイルは、ツールを使って作成したACFファイル(.*acf)、ACBファイル(.*acb)、AWBファイル(*.awb)と、同時に出力されるヘッダーファイル(*.h)です。 本チュートリアルでは、サンプルプログラムと同じデータを使用します。具体的には以下のファイルです。
本チュートリアルで使用するデータ
  * cri

  \ * common

    \ * smpdata

      \ * criatomex

        o * TutorialProject.acf

        o * tutorial_streaming.acb

        o * tutorial_streaming.h

        \ * tutorial_streaming_streamfiles.awb

 

 

: チュートリアルプログラム

 

: ACFファイル

: ACBファイル

: ACBヘッダーファイル

: AWBファイル

 

プロジェクトファイルとソースコード

チュートリアルのプロジェクトファイルとソースコードは以下の場所にあります。
チュートリアルソースコードの場所
  * cri

  \ * pc

    \ * tutorials

      \ * criatomex

        \ * playback_cue_streaming

          o * pcvc

          | o * playback_cue_streaming.sln

          | o * playback_cue_streaming.vcxproj

          | \ * playback_cue_streaming.vcxproj.filters

          |  

          \ * playback_cue_streaming.c

 

[プラットフォーム固有]

: チュートリアルプログラム

 

: キュー再生チュートリアル

: プロジェクトファイルフォルダー

: Visual Studio ソリューションファイル

: Visual Studio プロジェクトファイル

: Visual Studio フィルターファイル

 

: キュー再生チュートリアル

 

プログラムの流れ

プログラムの流れを以下に示します。キュー再生(メモリ) との違いは、 「3.D-BASの作成」「5.ボイスプールの作成」「7.再生開始」です。
  1. ヘッダーファイルのインクルード
  2. CRI Atomライブラリの初期化
  3. D-BASの作成
  4. 必要なファイルのロード
  5. ボイスプールの作成
  6. AtomExプレーヤの作成
  7. 再生開始
  8. 再生終了待ちと内部状態の更新
  9. 終了処理
  10. 再生の確認
/* CRI SDK Header */
#include <cri_xpt.h>

/* CRI ADX2 Headers */
#include <cri_atom_ex.h>
#include <cri_atom_wasapi.h>

/* チュートリアルで使用するACBファイルのヘッダーファイル */
#include  "../../../../common/smpdata/criatomex/tutorial_streaming.h"

/* データディレクトリへのパス */
#define PATH                "..\\..\\..\\..\\..\\common\\smpdata\\criatomex\\"

/* サンプルで使用するファイル名 */
#define ACF_FILE            "TutorialProject.acf"
#define ACB_FILE            "tutorial_streaming.acb"
#define AWB_FILE            "tutorial_streaming_streamfiles.awb"

/* main関数 */
CriSint32 main(CriSint32 argc, CriChar8 *argv[])
{
    CriAtomExStandardVoicePoolConfig voice_pool_config;
    CriAtomDbasId dbas_id;
    CriAtomExPlayerHn player;
    CriAtomExVoicePoolHn voice_pool;
    CriAtomExAcbHn acb_hn;

    UNUSED(argc);
    UNUSED(argv);

    /* 最低限の初期化 */
    tutorial_initialize();

    /* エラーコールバック関数の登録 */
    criErr_SetCallback(tutorial_error_callback_func);

    /* メモリアロケーターの登録 */
    criAtomEx_SetUserAllocator(tutorial_alloc, tutorial_free, NULL);
    
    /* ライブラリの初期化 */
    criAtomEx_Initialize_WASAPI(NULL, NULL, 0);

    /* D-BASの作成 */
    dbas_id = criAtomDbas_Create(NULL, NULL, 0);

    /* ACFファイルの読み込みと登録 */
    criAtomEx_RegisterAcfFile(NULL, PATH ACF_FILE, NULL, 0);
    
    /* ACBファイルを読み込み、ACBハンドルを作成 */
    acb_hn = criAtomExAcb_LoadAcbFile(
        NULL, PATH ACB_FILE, NULL, PATH AWB_FILE, NULL, 0);

    /* ボイスプールの作成 */
    criAtomExVoicePool_SetDefaultConfigForStandardVoicePool(&voice_pool_config);
    voice_pool_config.player_config.streaming_flag = CRI_TRUE;
    voice_pool = criAtomExVoicePool_AllocateStandardVoicePool(&voice_pool_config, NULL, 0);
    
    /* プレーヤの作成 */
    player = criAtomExPlayer_Create(NULL, NULL, 0);

    /* キューIDの指定 */
    criAtomExPlayer_SetCueId(player, acb_hn, CRI_TUTORIAL_STREAMING_MUSIC_TR);
    /* 再生の開始 */
    criAtomExPlayer_Start(player);

    for(;;) {
        CriAtomExPlayerStatus explayer_status;
        tutorial_sleep(10);
        /* サーバ処理の実行 */
        criAtomEx_ExecuteMain();

        /* Exプレーヤのステータス確認 */
        explayer_status = criAtomExPlayer_GetStatus(player);

        /* 再生が終了したらループを抜ける */
        if (explayer_status == CRIATOMEXPLAYER_STATUS_PLAYEND) {
            break;
        }
    }
    
    /* Atomハンドルの破棄 */
    criAtomExPlayer_Destroy(player);
    
    /* ボイスプールの破棄 */
    criAtomExVoicePool_Free(voice_pool);
    
    /* ACBハンドルの破棄 */
    criAtomExAcb_Release(acb_hn);

    /* ACFの登録解除 */
    criAtomEx_UnregisterAcf();

    /* D-BASの破棄 */
    criAtomDbas_Destroy(dbas_id);

    /* ライブラリの終了 */
    criAtomEx_Finalize_WASAPI();

    /*  最小限の終了処理*/
    tutorial_finalize();

    return 0;
}

プログラムの解説

各処理の詳細について説明します。
1.ヘッダーファイルのインクルード


/* CRI SDK Header */
#include <cri_xpt.h>

/* CRI ADX2 Headers */
#include <cri_atom_ex.h>
#include <cri_atom_wasapi.h>

/* チュートリアルで使用するACBファイルのヘッダーファイル */
#include  "../../../../common/smpdata/criatomex/tutorial_streaming.h"

cri_xpt.hは、CRI独自の型定義等が記述されているので、一番最初にインクルードします。 他のヘッダーファイルについては、インクルードする順番に依存関係はありません。
cri_atom_ex.hは、CRI Atomの機能を使うためのAPIが宣言されたヘッダーファイルです。 必ずインクルードしてください。
tutorial_streaming.hは、ACBファイル、AWBファイルのキュー情報が記述されたヘッダーファイルです。 再生するキューIDはこのヘッダーファイルに定数マクロ定義されています。
2.CRI Atomライブラリの初期化


    /* エラーコールバック関数の登録 */
    criErr_SetCallback(tutorial_error_callback_func);

    /* メモリアロケーターの登録 */
    criAtomEx_SetUserAllocator(tutorial_alloc, tutorial_free, NULL);
    
    /* ライブラリの初期化 */
    criAtomEx_Initialize_WASAPI(NULL, NULL, 0);

CRI Atomライブラリを初期化します。 本チュートリアルではcriAtomEx_Initialize_WASAPI関数に指定するパラメーターを簡略化しています。 criAtomEx_Initialize_WASAPI関数の第一引数は初期化パラメーターですが、NULLを指定するとデフォルト設定で初期化を行います。 criAtomEx_Initialize_WASAPI関数の第二、第三引数は、初期化に必要なワーク領域を指定するパラメーターです。 メモリ確保関数をcriAtomEx_SetUserAllocator関数で設定し、 ワーク領域へのポインタにNULL、ワークサイズに0を指定すると、criAtomEx_Initialize_WASAPI関数内部でワーク領域を動的に確保します。
3.D-BASの作成


    /* D-BASの作成 */
    dbas_id = criAtomDbas_Create(NULL, NULL, 0);

ストリーミング再生を行う場合は、再生を開始する前にcriAtomDbas_Create関数を使用してD-BASを作成します。 本チュートリアルではcriAtomDbas_Create関数に指定するパラメーターを簡略化しています。 criAtomDbas_Create関数の第一引数は初期化パラメーターですが、NULLを指定するとデフォルト設定で初期化を行います。 criAtomDbas_Create関数の第二、第三引数は、初期化に必要なワーク領域を指定するパラメーターです。 メモリ確保関数をcriAtomEx_SetUserAllocator関数で設定し、 ワーク領域へのポインタにNULL、ワークサイズに0を指定すると、criAtomDbas_Create関数内部でワーク領域を動的に確保します。
D-BASの役割は、プレーヤに対してストリーミングバッファを動的に分配することです。 ストリーミングバッファはブロック単位で管理され、各プレーヤが再生する音声データのビットレートに合わせて動的に分配されます。
本チュートリアルではエラー処理を省略していますが、criAtomDbas_Create関数は設定によっては必要なワークメモリが巨大になり、 エラーを返すことがあるので、戻り値のチェックを推奨します。
注意:
現在のバージョンでは、D-BASはアプリケーション中で1つまでしか作成できません。 今後リリースするバージョンでは、D-BASを複数個作成し、どのプレーヤにどのD-BASを割り当てるかをアプリケーションから指定できるようになる予定です。
4.必要なファイルのロード


    /* ACFファイルの読み込みと登録 */
    criAtomEx_RegisterAcfFile(NULL, PATH ACF_FILE, NULL, 0);
    
    /* ACBファイルを読み込み、ACBハンドルを作成 */
    acb_hn = criAtomExAcb_LoadAcbFile(
        NULL, PATH ACB_FILE, NULL, PATH AWB_FILE, NULL, 0);

criAtomEx_RegisterAcfFile関数を使用してACFファイルをランタイム側で読み込みます。 このファイルは環境設定ファイルです。 次に、criAtomExAcb_LoadAcbFile関数でACBファイルを読み込み、ハンドルを作成します。 ACBハンドルはキュー再生の際にプレーヤに指定します。
両関数ともワークサイズを指定する引数を取りますが、本チュートリアルでは簡略化のためにそれぞれNULL、0を指定しています。 NULL、0を指定することで、関数内部で動的にワーク領域を確保して使用します。
criAtomEx_RegisterAcfFile関数、criAtomExAcb_LoadAcbFile関数は同期関数です。 criAtomExAcb_LoadAcbFile関数の実行後は、ACBファイルのロードが完了し、 関数が成功していれば有効なACBハンドル(CriAtomExAcbHn)が返ります。
本チュートリアルではエラー処理を省略していますが、criAtomEx_RegisterAcfFile関数、 criAtomExAcb_LoadAcbFile関数は「ファイルがみつからない」といった理由で失敗することがあるため、 戻り値のチェックを推奨します。
5.ボイスプールの作成


    /* ボイスプールの作成 */
    criAtomExVoicePool_SetDefaultConfigForStandardVoicePool(&voice_pool_config);
    voice_pool_config.player_config.streaming_flag = CRI_TRUE;
    voice_pool = criAtomExVoicePool_AllocateStandardVoicePool(&voice_pool_config, NULL, 0);

本チュートリアルでは、ストリーミング用のキューを再生することを目的としています。 一方、ボイスプールの作成パラメーターを省略すると、デフォルトではストリーミングバッファを持たないボイスプールが作成されるため、 作成パラメーターを省略してしまうとストリーミング再生を行えません。 よって、本チュートリアルでは明示的に作成パラメーターを指定してボイスプールを作成します。
まず、CriAtomExStandardVoicePoolConfig型の変数を定義し、 criAtomExVoicePool_SetDefaultConfigForStandardVoicePool処理マクロを使ってボイス作成パラメーターを デフォルト値で初期化します。
次に、必要に応じてパラメーターを変更します。 ストリーミング再生可能なボイスプールを作成する場合、CriAtomExStandardVoicePoolConfigメンバーのplayer_configの設定を変更します。 player_config.streaming_flagにCRI_TRUE(デフォルト値はCRI_FALSE)を指定し、このパラメーターをcriAtomExVoicePool_AllocateStandardVoicePool関数に指定することで、 ストリーミング再生可能なボイスプールを作成できます。
本チュートリアルでは作成パラメーターを明示的に指定しましたが、ワークメモリの指定は作成パラメーターとは独立しており、今回も省略可能です。
6.AtomExプレーヤの作成


    /* プレーヤの作成 */
    player = criAtomExPlayer_Create(NULL, NULL, 0);

AtomExプレーヤ(以下、単にプレーヤと呼びます。)を作成します。
第一引数は作成パラメーターですが、本チュートリアルでは省略します。省略した場合、デフォルト値を使用してプレーヤを作成します。 プレーヤを作成するとプレーヤハンドル(CriAtomExPlayerHn)が得られます。 プレーヤに対する様々な操作は、このプレーヤハンドルを介して行います。
本チュートリアルではワークメモリを指定しません。 criAtomExPlayer_Create関数にワークメモリを指定しなかった場合(NULL指定、0サイズ)、 関数内部でメモリを動的に確保します。
7.再生開始


    /* キューIDの指定 */
    criAtomExPlayer_SetCueId(player, acb_hn, CRI_TUTORIAL_STREAMING_MUSIC_TR);
    /* 再生の開始 */
    criAtomExPlayer_Start(player);

再生するキューを criAtomExPlayer_SetCueId 関数で指定し、criAtomExPlayer_Start 関数で再生を開始します。 criAtomExPlayer_SetCueId関数の第二引数には、ロード済みのACBハンドルを指定します。 第三引数には、ACB内のキューをID(整数値)で指定します。
プレーヤは、指定されたACBハンドルとキューIDを元に、ACB内のキューデータを再生します。 本チュートリアルで指定している CRI_TUTORIAL_STREAMING_MUSIC_TR は、tutorial_streaming.hで定義されています。 キューシートヘッダーファイルからでは判りませんが、CRI_TUTORIAL_STREAMING_MUSIC_TRはストリーミングキューです。
再生の開始はcriAtomExPlayer_Start関数で行います。 criAtomExPlayer_Create関数で作成したAtomプレーヤハンドルを指定します。
8.再生終了待ちと内部状態の更新


    /* 再生ループ */
    for(;;) {
        CriAtomExPlayerStatus explayer_status;
        tutorial_sleep(10);
        /* サーバー処理の実行 */
        criAtomEx_ExecuteMain();

        /* Exプレーヤのステータス確認 */
        explayer_status = criAtomExPlayer_GetStatus(player);

        /* 再生が終了したらループを抜ける */
        if (explayer_status == CRIATOMEXPLAYER_STATUS_PLAYEND) {
            break;
        }
    }

criAtomExPlayer_GetStatus関数でプレーヤの状態を取得し、 終了状態(CRIATOMEXPLAYER_STATUS_PLAYEND)になったら再生ループを抜けます。 再生ループ内では、CRI Atomのサーバー処理関数である criAtomEx_ExecuteMain関数を毎V呼びます。 毎V呼び出さないと音声データの読み込みが間に合わなくなり、音途切れの原因になります。 また、プレーヤの状態はCRI Atomのサーバー処理によって更新されるので、criAtomEx_ExecuteMain関数を呼び忘れないように注意してください。
9.終了処理


    /* Atomハンドルの破棄 */
    criAtomExPlayer_Destroy(player);
    
    /* ボイスプールの破棄 */
    criAtomExVoicePool_Free(voice_pool);
    
    /* ACBハンドルの破棄 */
    criAtomExAcb_Release(acb_hn);

    /* ACFの登録解除 */
    criAtomEx_UnregisterAcf();

    /* D-BASの破棄 */
    criAtomDbas_Destroy(dbas_id);

    /* ライブラリの終了 */
    criAtomEx_Finalize_WASAPI();

アプリケーションの終了時には、各ハンドルをそれぞれ対応する関数で破棄します。 ハンドル作成時に動的確保されたワーク領域は、それぞれ対応するハンドル破棄関数内で解放されます。 最後に、criAtomEx_Finalize_WASAPI関数でライブラリ終了処理を実行します。
10.再生の確認


ここまでの作業で、キューをストリーミング再生することはできたでしょうか? うまく再生できていれば、BGMが鳴るはずです。
Next:エラーハンドリング

CRI Middleware logo Copyright (c) 2006-2018 CRI Middleware Co., Ltd.