WisdomSoft - for your serial experiences.

サウンド制御

再生するサウンドを個別に管理し、プログラムから再生や停止、一時停止や再開を制御できます。

再生単位を取得する

SoundEffect クラスの Play() メソッドによるサウンドの再生は、再生するだけであれば簡単で便利ですが、再生後の制御ができません。サウンドを一時停止させたり、途中で停止させたりする必要がある場合は、サウンドの再生単位(インスタンス)を CreateInstance() メソッドから取得し、これを操作します。

SoundEffect クラス CreateInstance() メソッド
public SoundEffectInstance CreateInstance ()

このメソッドは、サウンドの再生単位を表す Microsoft.Xna.Framework.Audio.SoundEffectInstance クラスのオブジェクトを返します。再生されるサウンドの流れは、この SoundEffectInstance オブジェクトによって管理されます。

Microsoft.Xna.Framework.Audio.SoundEffectInstance クラス
public class SoundEffectInstance : IDisposable

例えば、サウンドを 2 つ重ねて再生する場合、内部では 2 つの SoundEffectInstance オブジェクトが生成され、再生されています。同一の SoundEffect オブジェクトによって生成された SoundEffectInstance オブジェクトは、SoundEffect オブジェクトが持つ音声データを共有します。よって、SoundEffectInstance オブジェクトの生成がリソースを大きく消費することはありません。ただし、同時に SoundEffectInstance オブジェクトが存在できる数は、環境によって制限されます。Windows PC では制限はありませんが、Xbox 360 の場合は 300 が上限です。

CreateInstance() メソッドで生成した SoundEffectInstance オブジェクトのサウンドを再生するには Play() メソッドを呼び出します。これだけでは SoundEffect クラスの Play() メソッドと同じですが、SoundEffectInstance クラスは再生したサウンドを一時停止する Pause() メソッド、一時停止した位置から再生を再開する Resume() メソッド、再生を停止する Stop() メソッドを提供します。

SoundEffectInstance クラス Play() メソッド
public virtual void Play ()
SoundEffectInstance クラス Pause() メソッド
public void Pause ()
SoundEffectInstance クラス Resume () メソッド
public void Resume ()
SoundEffectInstance クラス Stop() メソッド
public void Stop ()

Pause() メソッドで一時停止したサウンドは、Resume() メソッドで停止した場所から再生を再開できます。一方、Stop() メソッドで停止させた場合は、再生位置がサウンドの先頭に戻ります。最後までサウンドを再生するか、または Stop() メソッドでサウンドを停止した状態から、再び Play() メソッドでサウンドの先頭から再生することも可能です。

現在の SoundEffectInstance オブジェクトが再生中なのか、停止しているのか、あるいは中断されているのかといった状態は State プロパティから取得できます。

SoundEffectInstance クラス State プロパティ
public SoundState State { get; }

このプロパティは、サウンドの状態を表す Microsoft.Xna.Framework.Audio.SoundState 列挙体のいずれかのメンバを返します。 

Microsoft.Xna.Framework.Audio.SoundState 列挙体
public enum SoundState

この列挙型は、再生中を表す Playing メンバ、一時停止を表す Paused メンバ、停止を表す Stopped メンバを持ちます。State プロパティから取得した値と SoundState 列挙型のメンバを比較することで、サウンドが再生中かどうかを調べられます。

コード1
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;

public class TestGame : Game
{
    public static void Main(string[] args)
    {
        using (Game game = new TestGame()) game.Run();
    }

    private GraphicsDeviceManager graphicsDeviceManager;
    private SoundEffect soundEffect;
    private SoundEffectInstance seInstance;
    private KeyboardState prevKeyState;

    public TestGame()
    {
        graphicsDeviceManager = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void LoadContent()
    {
        soundEffect = Content.Load<SoundEffect>("TestSound");
        seInstance = soundEffect.CreateInstance();
        base.LoadContent();
    }
    
    protected override void Update(GameTime gameTime)
    {
        KeyboardState keyState = Keyboard.GetState();
        if (keyState.IsKeyDown(Keys.Enter) && prevKeyState.IsKeyUp(Keys.Enter))
        {
            if (seInstance.State == SoundState.Stopped)
            {
                seInstance.Play();
            }
            else if (seInstance.State == SoundState.Playing)
            {
                seInstance.Pause();
            }
            else if (seInstance.State == SoundState.Paused)
            {
                seInstance.Resume();
            }
        }

        Window.Title = "State=" + seInstance.State;
        prevKeyState = keyState;

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.White);
        base.Draw(gameTime);
    }
}
実行結果
コード1 実行結果

コード1は LoadContent() メソッドで読み込んだ SoundEffect オブジェクトの CreateInstance() メソッドを呼び出し、対象のサウンド再生を管理する 1 つの SoundEffectInstance オブジェクトを取得しています。Update() メソッド内で Enter キーが押されたかどうかを調べ、Enter キーが押されるとサウンドの状態に合わせて再生や一時停止を行います。

この時 SoundEffectInstance クラスの State プロパティを用いてサウンドの状態を調べています。サウンドが停止していれば Play() メソッドを呼び出し、再生中であれば Pause() メソッドを呼び出して一時停止します。一時停止中であれば Resume() メソッドで再開します。サウンドが最後まで再生されれば、再びサウンドは停止状態になります。サウンドの状態は、ウィンドウのタイトルバーにも表示しています。