サウンドの再生と停止

Page creation date :

The page you are currently viewing does not support the selected display language.

再生ボタンを押すと曲が再生され、停止ボタンを押すと停止します。

サウンドの再生と停止

今回のメインコードファイルを載せます。部分的な説明に関してはコードの下の方で説明しています。

MainFrom.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;

namespace MDXSample
{
    /// <summary>
    /// メインフォーム
    /// </summary>
    public partial class MainForm : Form
    {
        /// <summary>
        /// DirectSound デバイス
        /// </summary>
        private Device _device = null;

        /// <summary>
        /// セカンダリバッファ
        /// </summary>
        private SecondaryBuffer _buffer = null;


        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
        }
        /// <summary>
        /// フォームが表示される直前
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                // デバイスの作成
                this._device = new Device();

                // 協調レベルの設定
                this._device.SetCooperativeLevel(this, CooperativeLevel.Priority);

                // セカンダリバッファにファイルからバッファをロードします
                this._buffer = new SecondaryBuffer("../../Sample.wav", this._device);
            }
            catch (Exception ex)
            {
                // 失敗
                MessageBox.Show(ex.ToString(), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        /// <summary>
        /// フォームが閉じられる直前
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            // セカンダリバッファの破棄
            if (this._buffer != null)
            {
                this._buffer.Dispose();
            }

            // デバイスの破棄
            if (this._device != null)
            {
                this._device.Dispose();
            }
        }
        /// <summary>
        /// 再生ボタンを押したとき
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonPlay_Click(object sender, EventArgs e)
        {
            if (this._buffer != null)
            {
                // 再生位置を一番最初に設定
                this._buffer.SetCurrentPosition(0);

                // 再生
                this._buffer.Play(0, BufferPlayFlags.Default);
            }
        }
        /// <summary>
        /// 停止ボタンを押したとき
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonStop_Click(object sender, EventArgs e)
        {
            if (this._buffer != null)
            {
                // 停止
                this._buffer.Stop();
            }
        }
    }
}

/// <summary>
/// DirectSound デバイス
/// </summary>
private Device _device = null;

DirectSound を使用するには必ず「Device」クラスを作成する必要があります。このクラスを使用して環境の設定やバッファオブジェクトの作成を行います。


/// <summary>
/// セカンダリバッファ
/// </summary>
private SecondaryBuffer _buffer = null;

セカンダリバッファとは、サウンドデータをバッファとして格納し、再生、エフェクトなどの操作を行うためのクラスです。実はセカンダリバッファの他にプライマリバッファというものがあるのですが、こっちは直接サウンドカードなどのデバイスにアクセスして操作するものです。通常プライマリバッファは直接使うことは無く、セカンダリバッファを使うのが普通です。


try
{
    // デバイスの作成
    this._device = new Device();

    // 協調レベルの設定
    this._device.SetCooperativeLevel(this, CooperativeLevel.Priority);

    // セカンダリバッファにファイルからバッファをロードします
    this._buffer = new SecondaryBuffer("../../Sample.wav", this._device);
}
catch (Exception ex)
{
    // 失敗
    MessageBox.Show(ex.ToString(), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

まず一番最初に Device クラスを作成します。特に渡す引数はないので注意するところはありません。一番最初に作成するものと覚えておいてください。

次に「Device.SetCooperativeLevel」で協調レベルというものを設定します。これは他のアプリケーションが同時にオーディオ機能を使用するときにデバイスの切り替えなどに影響します。また、プライマリバッファの設定や操作などにも関わってきます。  通常他のアプリケーションと同時にデバイスを使用することはあまりないので、「CooperativeLevel.Priority」で優先協調レベルを設定しても問題ないでしょう。  詳しくは下を参照してください。

Device.SetCooperativeLevel メソッド

このサウンド デバイスに対するアプリケーションの協調レベルを設定します。
owner 対象となるコントロール。通常メインで使用しているフォームを指定
level 協調レベル。CooperativeLevel から指定する。下を参照

CooperativeLevel 列挙型

Normal このフラグを指定するとプライマリバッファを「周波数 22Kz」「ステレオサウンド」「8ビットサンプリング」としてしか使用できません。ただし、他のアプリケーションも Normal を使用している場合は、デバイスの切り替えがとてもスムーズに行えます。
Priority ハードウェアに近い処理を行うことが出来ます。より細かい設定を行う場合はこのフラグを使用します。ゲームなどではこのフラグを使用するのが一般的です。
WritePrimary プライマリバッファに直接データを書き込むことが出来ます。ただしこの場合セカンダリバッファを使用することは出来ません。基本的に独自制御になるので、単純な再生目的程度であれば通常このフラグは使用しません。

協調レベルを設定したら、セカンダリバッファを作成しています。第1引数にサウンドデータファイルを指定し、第2引数には先ほど作成した Device を指定します。サウンドデータファイルは WAVE ファイルのみ指定可能です。他の形式のファイルは直接指定することは出来ません。

何らかの例外が発生した場合はメッセージボックスを表示させています。


// セカンダリバッファの破棄
if (this._buffer != null)
{
    this._buffer.Dispose();
}

// デバイスの破棄
if (this._device != null)
{
    this._device.Dispose();
}

フォームを閉じたときには、セカンダリバッファとデバイスのリソースを破棄しています。


if (this._buffer != null)
{
    // 再生位置を一番最初に設定
    this._buffer.SetCurrentPosition(0);

    // 再生
    this._buffer.Play(0, BufferPlayFlags.Default);
}

再生ボタンを押したときの処理です。バッファが作成されている場合に再生する処理を行っています。

まず初めに「SecondaryBuffer.SetCurrentPosition」で再生を開始する位置を指定しています。0 を指定すると曲の最初から再生することになります。  もちろんこのメソッドで任意の場所から再生したり、逆にこのメソッドを使用しなければ、前回停止した位置から再生し直すことも出来たりします。  ちなみにここで指定する値の単位は、「バッファのバイト単位」です。最大値は WAVE ファイルのサイズにかなり近い数値になると思います。もちろんファイルサイズはあくまでもファイルサイズなので正確ではありません、本来のバッファサイズの求め方は下のようになります。

Size = サンプリングレート(kz) × チャンネル数 × 1サンプルあたりのビット数 ÷ 8 × 再生時間(s)

サウンドを再生するには「SecondaryBuffer.Play」メソッドを使用します。第1引数はサウンドの優先度です。特に無ければ 0 でかまいません。第2引数は再生フラグです。大抵は1回再生の「BufferPlayFlags.Default」かループ再生の「BufferPlayFlags.Looping」を使用します。


if (this._buffer != null)
{
    // 停止
    this._buffer.Stop();
}

サウンドを再生していた場合は「SecondaryBuffer.Stop」で停止します。このメソッドを使用して停止した場合は、再生カーソルはその直後に設定されるため、「SecondaryBuffer.Play」を使用して続きから再生させることも出来ます。