サウンド - フェードアウト2013/11/26

前回のサウンド管理クラスで、サウンドプレイヤーをシステムで管理できるようになりました。
今回はプレイヤーに毎フレーム実行する処理を加え、サウンドのフェードアウトを実装してみます。


Sound.h
	float			volume;						// 音量
	float			fade_volume;				// フェードアウト音量

クラス sys::SoundPlayerのメンバ変数です。
フェードアウト時に使用する fade_volumeが追加されています。


Sound.cpp
/*************************************
    停止
		引数	_cnt = フェード時間
 *************************************/
void	SoundPlayer::stop(int _cnt)
{
	if ( bqPlayerObject ) {					// 再生中
		if ( (_cnt == 0) || (volume == 0.0f) ) {
			(*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);			// 停止状態
			(*bqPlayerObject)->Destroy(bqPlayerObject);
			bqPlayerObject = NULL;
			if ( format == FORMAT_OGG ) {
				::ov_clear(&ov_file);
				format = -1;
			}
			if ( sound_data ) {
				delete	sound_data;
				sound_data = NULL;
			}
		}
		else {
			fade_volume = volume/_cnt;
			return;
		}
	}
	state = STOPPED;
}

サウンド停止関数の引数にフェードアウトする時間(フレーム単位)を追加しました。現在の音量と時間から1フレームの減衰量を fade_volumeに設定します。
時間が0、または音量がすでに0になっている場合は今までと同様に停止処理を行います。

/**********
    稼働
 **********/
void	SoundPlayer::update(void)
{
	switch ( state ) {
	  case STOPPED :						// 停止中
		if ( bqPlayerObject ) {	
			(*bqPlayerObject)->Destroy(bqPlayerObject);
			bqPlayerObject = NULL;
		}
		break;

	  case PLAYING :						// 再生中
		if ( fade_volume > 0.0f ) {
			volume -= fade_volume;
			if ( volume <= 0.0f ) {
				stop();
			}
			else {
				set_volume();
			}
		}
		break;
	}
}

フレーム毎に呼び出される処理です。
再生時、fade_volumeが0以上であればフェードアウト処理(音量を減衰)を行います。

ついでに、停止時プレイヤーオブジェクトが残っている場合に削除しています。終端まで再生して自然に停止したときオブジェクトは残ってしまいますが、使っていないオブジェクトは削除しておいた方が良さそうなので。

/**********
    稼働
 **********/
void	SoundManager::update(void)
{
	for (int i = 0; i < SOUND_CHANNEL_MAX; i++) {
		player[i].update();
	}
}

サウンド管理クラスから、各プレイヤーの稼働処理を呼んでいます。
この関数はシステムのメインループから呼ばれています。


サンプルでは、画面をタッチする度にBGMのフェードアウトと再生を交互に繰り返します。
停止関数 stopにフェード時間を指定しているだけなので、説明は省略します。

プロジェクト一式は、こちらから。