その2

なんとかDirectSoundを使った再生用サウンドクラス完成かな^〜^

  1. 使うときはフォーム側で先にクラス宣言しとかないと一回目の再生だけコントロール操作が入るとおわっちゃうかも。(宣言と同時にインスタンス作成するとあうち)でも、コンストラクタと再生部を分離したからええのかもw<チェキしろよ!
  2. Microsoft.DirectX.AudioVideoPlaybackのAudioだと、再生中かどうかのチェック不可なのがあんぽんたん´〜`(常に再生フラグオン)
  3. DeviceやSecondaryBufferの自動Dispose()機能つけたのでnewしまくってもそうそうおかしくならないはず。

以下ソースコードなり。


/// <summary>
/// サウンドクラスDSoundWrapper用のフラグです。
/// </summary>
//フラグとして扱うときはフラグ属性をつける!
[Flags()]
public enum SoundFlags : int
{
None = 0x0,
PlaySync = 0x1,
PlayAsync = 0x2,
PlayWithExternalFile = 0x10,
PlayWithEmbededFile = 0x20
}


public class DSoundWrapper
{
/// <summary>
/// フィールドです。
/// </summary>
#region "Field:"
Device device = null;
BufferDescription desc = null;
SecondaryBuffer sound = null;
//Audioをつかうのだったらこんなかんじ(1/2)
//Audio audio = null;
#endregion

/// <summary>
/// コンストラクタです。
/// </summary>
#region "Constructor:"
public DSoundWrapper()
{
}
#endregion

/// <summary>
/// メソッドです。
/// </summary>
#region "Method:"
/// <summary>
/// Method: (外部or埋め込みの)ファイルからWaveデータを読み込み、再生します。
/// </summary>
/// <param name="myControl"></param>
/// <param name="soundFileName"></param>
/// <param name="soundFlags"></param>
public void Play(Control myControl, string soundFileName, SoundFlags soundFlags)
{
//using Microsoft.DirectX.DirectSound;
//Device取得
device = new Device();
device.SetCooperativeLevel(myControl, CooperativeLevel.Normal);
//BufferDescription設定
desc = new BufferDescription();
desc.ControlPan = true;
desc.GlobalFocus = true;

Console.WriteLine( "サウンドフラグは、{0} です。", soundFlags );
Console.WriteLine( "サウンドファイルは、{0} です。", soundFileName );

//SecondaryBuffer作成
//外部ファイルから?
if((soundFlags & SoundFlags.PlayWithExternalFile) != SoundFlags.None)
{
//外部ファイルからバッファ作成
sound = new SecondaryBuffer(soundFileName, desc, device);
}
else
{
//埋め込みファイルからバッファ作成
//using System.Reflection;
//現在実行中のアセンブリを取得
Assembly thisExe = Assembly.GetExecutingAssembly();
string assemblyName = thisExe.GetName().Name;
//埋め込みファイルのストリームを取得
Stream stream = thisExe.GetManifestResourceStream(assemblyName + "." + soundFileName);
//ストリームからバッファ作成
sound = new SecondaryBuffer(stream, desc, device);
//ストリームを閉じる!
stream.Close();
}

//再生フラグは同期?
if((soundFlags & SoundFlags.PlaySync) != SoundFlags.None)
{
//同期でした
PlaySync();
}
else
{
//非同期でした
PlayAsync();
}

//Audioをつかうのだったらこんなかんじ(2/2)
/*
audio = new Audio(soundFileName);
audio.Play();
・・・演奏終了確認・・・
audio.Dispose();
*/

}

/// <summary>
/// Method: 同期再生
/// </summary>
private void PlaySync()
{
sound.Play(0, BufferPlayFlags.Default);

while(sound.Status.Playing)
{
Thread.Sleep(1000);
}

sound.Dispose();
desc.Dispose();
device.Dispose();
}

/// <summary>
/// Method: 非同期再生(別スレッドでPlaySync()を動作させる)
/// </summary>
private void PlayAsync()
{
//Playメソッドを別のスレッドで実行する
//Threadオブジェクトを作成する
System.Threading.Thread t =
new System.Threading.Thread(
new System.Threading.ThreadStart(PlaySync));
t.IsBackground = true;
//スレッドを開始する
t.Start();
}
#endregion
}

しかし、元々は画像重ね合わせソフトで終了音出すだけのはずがこんなになってしまいましたなあ。