サウンド処理は非同期で その3 ― 2013/11/30
サウンド管理でコマンドを javaに送る処理、そしてキューの中身を受け取ってサウンドプレイヤーの処理を実行する部分を作成します。これでサウンドの非同期処理の実装完了となります。
Sound.cpp
サウンド管理終了時、まだキューにコマンドが残っている可能性がありますので java側の関数を呼んでクリアしています。
再生などサウンドのコマンドを受け取る処理です。
直接サウンドプレイヤーの処理を呼んでいたのを、キューにコマンドを送るように変更しています。
javaからコマンドを受け取って実行する部分です。
コマンドの値に従ってサウンドプレイヤーの関数を呼び出しています。
再生・停止など命令がいろいろあるので処理は多いですが、どれもやっていることは同じです。
サウンドの命令自体は同じなので、サンプルに変更はありません。
プロジェクト一式は、こちらから。
Sound.cpp
/**********
終了
**********/
void SoundManager::quit(void)
{
{ // コマンド停止
JNIEnv* env;
Bool attach_flag = FALSE;
if ( g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6) < 0 ) {
if ( g_JavaVM->AttachCurrentThread(&env, NULL) < 0 ) {
goto error;
}
attach_flag = TRUE;
}
jclass clazz = env->FindClass("sys/SoundManager");
if ( clazz ) {
jmethodID mid = env->GetStaticMethodID(clazz, "stop_command", "()V");
if ( mid ) {
env->CallStaticVoidMethod(clazz, mid);
}
}
if ( attach_flag ) {
g_JavaVM->DetachCurrentThread();
}
}
error :
if ( player ) {
delete[] player;
player = NULL;
}
SoundPlayer::quit_engine(); // サウンドエンジン終了
}
サウンド管理終了時、まだキューにコマンドが残っている可能性がありますので java側の関数を呼んでクリアしています。
// サウンドコマンド
enum
{
COMMAND_UPDATE, // 稼働
COMMAND_PREPARE, // 準備
COMMAND_PLAY, // 再生・再開
COMMAND_STOP, // 停止
COMMAND_VOLUME, // 音量設定
COMMAND_NEXT, // 連続再生設定
COMMAND_PAUSE, // 一時停止
COMMAND_PAUSE_SYS,
COMMAND_RESUME, // 再開
COMMAND_RESUME_SYS,
};
/**********
稼働
**********/
void SoundManager::update(void)
{
set_command(-1, COMMAND_UPDATE);
}
/********************************************************
再生
引数 _channel = チャンネル番号
_data = サウンドデータ
_size = サウンドデータサイズ
_loop = ループ回数(0:無限ループ)
_vol = 音量
*******************************************************/
void SoundManager::prepare(int _channel, const void* _data, u32 _size, int _loop, float _vol)
{
assert((0 <= _channel) && (_channel < SOUND_CHANNEL_MAX));
set_command(_channel, COMMAND_PREPARE, _data, _size, _loop, _vol);
}
void SoundManager::play(int _channel)
{
assert((0 <= _channel) && (_channel < SOUND_CHANNEL_MAX));
set_command(_channel, COMMAND_PLAY);
}
void SoundManager::play(int _channel, const void* _data, u32 _size, int _loop, float _vol)
{
assert((0 <= _channel) && (_channel < SOUND_CHANNEL_MAX));
set_command(_channel, COMMAND_PLAY, _data, _size, _loop, _vol);
}
void SoundManager::play(void)
{
set_command(-1, COMMAND_PLAY); // 全て再生開始
}
/*******************************************
停止
引数 _channel = チャンネル番号
_cnt = フェード時間
*******************************************/
void SoundManager::stop(int _channel, int _cnt)
{
assert((0 <= _channel) && (_channel < SOUND_CHANNEL_MAX));
set_command(_channel, COMMAND_STOP, NULL, (u32)_cnt);
}
void SoundManager::stop(void)
{
set_command(-1, COMMAND_STOP); // 全て停止
}
/*********************************************************
音量設定
引数 _channel = チャンネル番号
_vol = 音量(0.0:最小 ~ 1.0:最大)
*********************************************************/
void SoundManager::set_volume(int _channel, float _vol)
{
assert((0 <= _channel) && (_channel < SOUND_CHANNEL_MAX));
set_command(_channel, COMMAND_VOLUME, NULL, 0, 0, _vol);
}
/*****************************************************
マスター音量設定
引数 _vol = 音量(0.0:最小 ~ 1.0:最大)
*****************************************************/
void SoundManager::set_master_volume(float _vol)
{
set_command(-1, COMMAND_VOLUME, NULL, 0, 0, _vol);
}
/*******************************************************
連続再生設定
引数 _channel = チャンネル番号
_data = サウンドデータ
_size = サウンドデータサイズ
_loop = ループ回数(0:無限ループ)
*******************************************************/
void SoundManager::set_next(int _channel, const void* _data, u32 _size, int _loop)
{
assert((0 <= _channel) && (_channel < SOUND_CHANNEL_MAX));
set_command(_channel, COMMAND_NEXT, _data, _size, _loop);
}
/*********************************************
一時停止
引数 _channel = チャンネル番号
*********************************************/
void SoundManager::pause(int _channel)
{
assert((0 <= _channel) && (_channel < SOUND_CHANNEL_MAX));
set_command(_channel, COMMAND_PAUSE);
}
void SoundManager::pause(void)
{
set_command(-1, COMMAND_PAUSE); // 全て一時停止
}
void SoundManager::pause_system(void) // システムによる一時停止
{
set_command(-1, COMMAND_PAUSE_SYS);
}
/*********************************************
再開
引数 _channel = チャンネル番号
*********************************************/
void SoundManager::resume(int _channel)
{
assert((0 <= _channel) && (_channel < SOUND_CHANNEL_MAX));
set_command(_channel, COMMAND_RESUME);
}
void SoundManager::resume(void)
{
set_command(-1, COMMAND_RESUME); // 全て再開
}
void SoundManager::resume_system(void) // システムによる再開
{
set_command(-1, COMMAND_RESUME_SYS);
}
再生などサウンドのコマンドを受け取る処理です。
直接サウンドプレイヤーの処理を呼んでいたのを、キューにコマンドを送るように変更しています。
/********************************
Javaからコマンドを受け取る
********************************/
extern "C"
{
JNIEXPORT void JNICALL Java_sys_SoundManager_sendSoundCommand(JNIEnv*, jobject, jshort, jshort, jint, jint, jshort, jfloat);
}
JNIEXPORT void JNICALL Java_sys_SoundManager_sendSoundCommand(JNIEnv*, jobject,
jshort _channel, jshort _command, jint _data, jint _size, jshort _loop, jfloat _volume)
{
SoundManager::get_command((int)_channel, (int)_command, (void*)_data, (u32)_size, (int)_loop, (float)_volume);
}
void SoundManager::get_command(int _channel, int _command, void* _data, u32 _size, int _loop, float _volume)
{
switch ( _command ) {
case COMMAND_UPDATE :
for (int i = 0; i < SOUND_CHANNEL_MAX; i++) {
player[i].update();
}
break;
case COMMAND_PREPARE :
player[_channel].prepare(_data, _size, _loop, _volume);
break;
case COMMAND_PLAY :
if ( _channel >= 0 ) {
if ( _size ) {
player[_channel].prepare(_data, _size, _loop, _volume);
}
player[_channel].play();
}
else {
for (int i = 0; i < SOUND_CHANNEL_MAX; i++) { // 全て再開
player[i].play();
}
}
break;
case COMMAND_STOP :
if ( _channel >= 0 ) {
player[_channel].stop((int)_size);
}
else {
for (int i = 0; i < SOUND_CHANNEL_MAX; i++) { // 全て停止
player[i].stop();
}
}
break;
case COMMAND_VOLUME :
if ( _channel >= 0 ) {
player[_channel].set_volume(_volume);
}
else if ( SoundPlayer::set_master_volume(_volume) ) { // マスター音量設定
for (int i = 0; i < SOUND_CHANNEL_MAX; i++) {
player[i].set_volume(); // 音量再設定
}
}
break;
case COMMAND_NEXT :
player[_channel].set_next(_data, _size, _loop);
break;
case COMMAND_PAUSE :
if ( _channel >= 0 ) {
player[_channel].pause(TRUE);
}
else {
for (int i = 0; i < SOUND_CHANNEL_MAX; i++) { // 全て一時停止
player[i].pause(TRUE);
}
}
break;
case COMMAND_PAUSE_SYS :
for (int i = 0; i < SOUND_CHANNEL_MAX; i++) { // システムによる再開
player[i].pause(FALSE);
}
break;
case COMMAND_RESUME :
if ( _channel >= 0 ) {
player[_channel].resume();
}
else if ( _size ) {
for (int i = 0; i < SOUND_CHANNEL_MAX; i++) { // 全て再開
player[i].resume();
}
}
break;
case COMMAND_RESUME_SYS :
for (int i = 0; i < SOUND_CHANNEL_MAX; i++) { // システムによる再開
player[i].resume(SoundPlayer::PLAYING);
}
break;
}
}
javaからコマンドを受け取って実行する部分です。
コマンドの値に従ってサウンドプレイヤーの関数を呼び出しています。
再生・停止など命令がいろいろあるので処理は多いですが、どれもやっていることは同じです。
サウンドの命令自体は同じなので、サンプルに変更はありません。
プロジェクト一式は、こちらから。
最近のコメント