何をしたのか?
ADX2のデータをちょっとプレビューしたい時に便利なツールをつくってみた。
C++でADX2LE を参考に
ソースコード
SoundManager.h
# pragma once
# include <cri_xpt.h>
# include <cri_atom_wasapi.h>
# include <iostream>
# include <string>
# include <iterator>
# include <vector>
# include <cctype>
using namespace std;
class SoundManager
{
public:
SoundManager(char* acf_file, char* acb_file, char* awb_file);
~SoundManager();
//void Play(string &mml);
void Play(const char* cueName);
private:
/* エラーコールバック関数 */
static void user_error_callback_func(const CriChar8 *errid, CriUint32 p1, CriUint32 p2, CriUint32 *parray)
{
const CriChar8 *errmsg;
/* エラー文字列の表示 */
errmsg = criErr_ConvertIdToMessage(errid, p1, p2);
cout << ("%s\n", errmsg);
return;
}
static void *user_alloc_func(void *obj, CriUint32 size)
{
void *ptr;
ptr = malloc(size);
return ptr;
}
static void user_free_func(void *obj, void *ptr)
{
free(ptr);
}
private:
CriAtomExPlayerHn player; /* 再生プレーヤ */
CriAtomExVoicePoolHn voice_pool; /* ボイスプール */
CriAtomExAcbHn acb_hn; /* ACBハンドル(音声データ) */
CriAtomDbasId dbas_id; /* D-BASの作成*/
CriAtomExPlaybackId playback_id; /* VoiceキューのプレイバックID(再生開始時に保持する) */
};
SoundManager.cpp
# include "SoundManager.h"
/* 最大ボイス数を増やすための関連パラメータ */
# define MAX_VOICE (24)
# define MAX_VIRTUAL_VOICE (MAX_VOICE + 8) /* バーチャルボイスは多め */
# define MAX_CRIFS_LOADER (MAX_VOICE + 8) /* 読み込み数も多めに */
/* 最大サンプリングレート(ピッチ変更含む) */
# define MAX_SAMPLING_RATE (48000*4)
SoundManager::SoundManager(char* acf_file, char* acb_file, char* awb_file)
{
/* エラーコールバック関数の登録 */
criErr_SetCallback(user_error_callback_func);
/* メモリアロケータの登録 */
criAtomEx_SetUserAllocator(user_alloc_func, user_free_func, NULL);
/* ライブラリの初期化(最大ボイス数変更) */
CriAtomExConfig_WASAPI lib_config;
CriFsConfig fs_config;
criAtomEx_SetDefaultConfig_WASAPI(&lib_config);
criFs_SetDefaultConfig(&fs_config);
lib_config.atom_ex.max_virtual_voices = MAX_VIRTUAL_VOICE;
fs_config.num_loaders = MAX_CRIFS_LOADER;
lib_config.atom_ex.fs_config = &fs_config;
criAtomEx_Initialize_WASAPI(&lib_config, NULL, 0);
/* D-Basの作成(最大ストリーム数はここで決まります) */
dbas_id = criAtomDbas_Create(NULL, NULL, 0);
/* ACFファイルの読み込みと登録 */
criAtomEx_RegisterAcfFile(NULL, acf_file, NULL, 0);
/* DSP設定のアタッチ */
criAtomEx_AttachDspBusSetting("DspBusSetting_0", NULL, 0);
/* ボイスプールの作成(最大ボイス数変更/最大ピッチ変更/ストリーム再生対応) */
CriAtomExStandardVoicePoolConfig vpool_config;
criAtomExVoicePool_SetDefaultConfigForStandardVoicePool(&vpool_config);
vpool_config.num_voices = MAX_VOICE;
vpool_config.player_config.max_sampling_rate = MAX_SAMPLING_RATE;
vpool_config.player_config.streaming_flag = CRI_TRUE;
voice_pool = criAtomExVoicePool_AllocateStandardVoicePool(&vpool_config, NULL, 0);
/* ACBファイルを読み込み、ACBハンドルを作成 */
acb_hn = criAtomExAcb_LoadAcbFile(NULL, acb_file, NULL, awb_file, NULL, 0);
/* プレーヤの作成 */
player = criAtomExPlayer_Create(NULL, NULL, 0);
criAtomExPlayer_SetCueId(player, acb_hn, 1);
}
SoundManager::~SoundManager()
{
/* DSPのデタッチ */
criAtomEx_DetachDspBusSetting();
/* プレーヤハンドルの破棄 */
criAtomExPlayer_Destroy(player);
/* ボイスプールの破棄 */
criAtomExVoicePool_Free(voice_pool);
/* ACBハンドルの破棄 */
criAtomExAcb_Release(acb_hn);
/* ACFの登録解除 */
criAtomEx_UnregisterAcf();
/* D-BASの破棄 */
criAtomDbas_Destroy(dbas_id);
/* ライブラリの終了 */
criAtomEx_Finalize_WASAPI();
}
void SoundManager::Play(const char* cueName)
{
criAtomExPlayer_SetCueName(player, NULL, cueName);
playback_id = criAtomExPlayer_Start(player);
{
while (true)
{
if (criAtomExPlayer_GetStatus(player) == CriAtomExPlayerStatus::CRIATOMEXPLAYER_STATUS_STOP)break;
if (criAtomExPlayer_GetStatus(player) == CriAtomExPlayerStatus::CRIATOMEXPLAYER_STATUS_ERROR)break;
if (criAtomExPlayer_GetStatus(player) == CriAtomExPlayerStatus::CRIATOMEXPLAYER_STATUS_PLAYEND)break;
Sleep(0);
}
cout << "end" << endl;
criAtomExPlayer_Stop(player);
}
}
adx2preview.cpp
# include <iostream>
# include "SoundManager.h"
using namespace std;
int main(int argc, char* argv[])
{
std::cout << argv[0] << std::endl;
std::cout << argv[1] << std::endl; //ACFパス
std::cout << argv[2] << std::endl; //ACBパス
std::cout << argv[3] << std::endl; //AWBパス
std::cout << argv[4] << std::endl; //キュー名
SoundManager sm(argv[1], argv[2], argv[3]);
sm.Play(argv[4]);
}
これをADX2のサンプルの設定とかを参考にコンソールツールとしてビルドする。
UnityEditor拡張から呼ぶ
EditorPreviewADX2.cpp
if (GUILayout.Button ("Editor時再生テストボタン")){
// 別アプリ(プロセス)起動
System.Diagnostics.Process proc = new System.Diagnostics.Process ();
proc.StartInfo.FileName = @"C:\Chronos\adx2preview\adx2preview\Release\adx2preview.exe";
proc.StartInfo.Arguments = "\"C:\\Chronos\\Assets\\StreamingAssets\\Megalith.acf\" \"C:\\Chronos\\Assets\\StreamingAssets\\BGM.acb\" \"C:\\Chronos\\Assets\\StreamingAssets\\BGM.awb\" \"Chronos\"";
proc.Start ();
}