効果音再生・停止:XAudio2の扱い方
この章では効果音(wavファイル)の再生・停止方法について解説します。
実行結果
今回のサンプルでは、XAudio2を使い効果音の再生・停止関数を用意します。 また使い方のサンプルとして、おおよそ5秒おきに(電車の通り過ぎる)効果音が流れるサンプルコードで実際に効果音を再生するアプリとなっています。
SharpDXを関連付け
必要なパッケージをインストール
- 「NuGet」を使った同じやり方で「SharpDX.XAudio2」をインストールします。
XAudio2の設定
ファイルの読み込み処理
- 処理に必要なファイルを関連付けます。
// サウンドファイルを扱う用 using System.IO; using SharpDX.XAudio2; using SharpDX.Multimedia;
- 音源を扱う変数を宣言します。
- XAudio2の初期化を行います。
try { // XAudio初期化 xaDevice = new XAudio2(); xaMaster = new MasteringVoice(xaDevice); } // vistaの時、スピーカーなどが接続されていない場合は生成できない catch { MessageBox.Show("サウンドデバイスの生成に失敗しました。", "エラー"); }
再生処理
- 効果音の処理を関数として作ります。
外部から効果音を好きに再生できるよう関数化して扱いやすくしておきます。/// 効果音の再生 public void PlaySound(string soundFileName) { switch (Path.GetExtension(soundFileName)) { case ".wav": { // サウンドデバイスが無い場合処理しない if (xaDevice == null) { return; } // WAVEファイルを読み込んで設定 using (SoundStream xaStream = new SoundStream(File.OpenRead(soundFileName))) { SourceVoice xaSource = new SourceVoice(xaDevice, xaStream.Format); AudioBuffer xaBuffer = new AudioBuffer() { // 読み込む容量 AudioBytes = (int)xaStream.Length, // WaveStreamを渡す Stream = xaStream, // ループ設定 LoopCount = XAudio2.NoLoopRegion, // ループ開始位置 LoopBegin = 0, // 再生する長さ。0だと全部。 LoopLength = 0, // 再生開始位置 PlayBegin = 0, PlayLength = 0, Flags = BufferFlags.EndOfStream, }; xaStream.Close(); if (xaSource != null) { xaSource.SubmitSourceBuffer(xaBuffer, xaStream.DecodedPacketsInfo); xaSource.SetVolume(1.0F); (xaSESourceList).Add(xaSource); xaSource.Start(); } } } break; } }
停止処理
- 効果音の処理を関数として作ります。
外部から効果音を好きに停止できるよう関数化して扱いやすくしておきます。
※この例では全効果音を一斉に停止させるものです。/// 効果音の停止 public void StopSound() { // サウンドデバイスが無い場合処理しない if (xaDevice == null) { return; } foreach (var n in xaSESourceList) { n.Stop(); n.Dispose(); } xaSESourceList.Clear(); }
サンプル:効果音の再生処理
- 効果音再生関数の使い方としてサンプル用のコードです。
定期的に効果音を鳴らすための変数を関数外に宣言します。/// 実行されてからのフレーム数 /// ※定期的に効果音を鳴らすための簡易処理に使用 int frame = 0;
- 効果音となるwav音源を用意してexeが生成されるフォルダ内に格納しておきます。
※今回効果音は、フリー音楽素材/魔王魂さんの素材「乗り物02」を使わせて頂きました。 - メインループ内で先ほどのフレーム数をカウントしていき、一定値以上になった際に効果音が流れる簡易的な定期処理となっています。
※ゲームなどで組み合わせる場合は、キーの入力や特定タイミングなどで同じように呼び出すようにしてください。// 簡易的な定期処理 // ※300フレームごと(=おおよそ5秒おき)に実行される if(frame % 300 == 0) { PlaySound("se_maoudamashii_se_vehicle02.wav"); } frame++;
- 上記処理をメインループ処理に組み込んで呼び出します。
解放処理
- XAudio2の解放処理を行います。
リソースの解放時にはXAudio2周りのクラスも解放するようにしておきます。foreach (var n in xaSESourceList) { n.Dispose(); } if (xaMaster != null) { xaMaster.Dispose(); } if (xaDevice != null) { xaDevice.Dispose(); }
コード
Program.cs
GameForm.cs