6-4 CDSPro81クラスを使おう!

CDSProクラスとはDirectSoundをもっと簡単に扱えるようにしたライブラリです。
このクラスもDirectX8.1を想定しているためCDSPro81という名前になっていますが、
別名でCDSProとも定義されているためどちらの名前を使用しても問題ありません。
※DirectSoundは8が最後のバージョンです


このソースコードは自由に改変して使用できます。
その際、有償無償関係なく使用できますが、もしバグがあった場合は責任は取れませんので、
十分デバッグしてから利用してください。


このクラスは標準的なWAVファイルのみに対応しており、MP3やOGGなどの形式には対応していません。
なおCDSProライブラリに外部ライブラリを追加することで対応は可能ですが、
現時点ではこれらのライブラリは提供していないため、必要ならば自前でデコーダーなどを組み込んでください。
※以前のサンプルではMP3用のデコーダーも提供していましたが、MP3は仕様上先頭部分に無音領域が生成されてしまい、
 音ゲーに使用すると曲と譜面がズレる原因となるため、現在はMP3を使用することはおススメしていません


■何が出来るの?

このクラスでは以下のことが行えます。

1.DirectSound、DirectSoundBufferの管理
2.RIFF形式のWAVファイルロード
3.再生・停止
4.再生位置を先頭へ戻す
5.ファイルごとの既定の再生周波数の取得
6.ファイルごとの再生周波数の設定

このライブラリを使用すれば、DirectSoundをまったく知らなくても音を鳴らすことが出来ます。
また各関数が専用に用意されているので、説明をする必要も無いくらい簡単に扱うことが出来ます。

このクラスは#pragma命令により自動的にdsound.libなどのライブラリにリンクするようになっています。

このライブラリはセカンダリサウンドバッファをスロットという概念で制御します。
1つのスロットには1つのWAVファイルを登録(ロード)することが出来ますが、
スロットにはID番号が割り当てられており、このID番号に対してサウンドをロードしたり、
また再生や停止を制御するといった形となっています。

スロット番号は0~CDSPRO_MAXSOUND-1まで指定出来ますが、
CDSPRO_MAXSOUNDは定数のため、ソースコードを変更することで扱えるサウンド数を変更することも出来ます。
※現時点ではCDSPRO_MAXSOUNDは2048と定義されています

■CDSPro81のダウンロード

CDSPro81ライブラリ v2.01 CDSPro81_v2.01.zip

サンプルプログラムなどで使用しているライブラリはこれより古い可能性があるため、
最新版は常にこちらからダウンロードするようにしてください。

CDSPro81クラスの他にいくつかの関連するクラスも含まれているため、
使用する場合はこれらのファイルも全てプロジェクトに追加する必要があります。

■サンプルプログラム

ここではCDSProクラスを使ったサンプルを見てみましょう。
このクラスを使用すればどれだけ簡単にサウンド再生が行えるかの参考になると思います。

サンプルのダウンロード

VisualStudio2010のプロジェクト
※VC2012、VC2013はこちら
CDSProSample_vs2010.zip
VisualStudio2015のプロジェクト CDSProSample_vs2015.zip

リリースビルドしたexeが入っているのでビルドせずとも実行することが出来ます。
※ビルド時に64bit版OSを使用している場合はこちらを参照してください

プログラム解説

このサンプルプログラムはBGMの他に4つのドラム音をロードし、
キーボード操作によりこのドラム音を任意に鳴らすことが出来ます。
曲に合わせてキーを押してみると面白いと思います。

キー設定
Z X C V
バス スネア クローズ
ハイハット
オープン
ハイハット


まずはCDSPro81.hをインクルードします。

#include "CDSPro81.h"


次にこのクラスをグローバル変数として実体を定義します。

CDSPro81    ds;         // DirectSound


WinMainにてこのライブラリの初期化を行いますが、DirectSoundはCOMを内部で使用しているため、
念のためCOMの初期化を行ってからCreateを呼び出します。

// メインルーチン
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
   :

    // COMの初期化
    CoInitialize( NULL );

    // DirectSound
    if( !ds.Create(win.hWnd) ) {
        // COMの終了
        CoUninitialize();
        return -1;
    }

Createの引数にはウィンドウハンドルの他にプライマリサウンドバッファのフォーマットを指定出来ますが、
ここでは全てデフォルトの値(CD音質)にて初期化を行っています。

次にBGMとドラム音をロードします。

    // サウンドの追加
    ds.AddSound( 0,"bgm.wav" );
    ds.AddSound( 1,"closehihat.wav" );
    ds.AddSound( 2,"openhihat.wav" );
    ds.AddSound( 3,"snare.wav" );
    ds.AddSound( 4,"bass.wav" );

サウンドのロードにはAddSoundを使用します。
この関数は第1引数にはスロット番号、第2引数にファイル名を指定します。
なお、同名の関数でメモリバッファからロードするものも用意されているので、
必要ならばヘッダファイルを確認してください。

このサンプルではメインループに入る前にBGMをループ再生しています。

    // 起動時の再生
    ds.Play( 0,TRUE );

    BOOL bOn[4] = { FALSE,FALSE,FALSE,FALSE };      // 連続押し回避
    MSG msg;
    while(1) {

BGMはスロット番号0にロードしてあるため、ここではPlayの第1引数に0を、
第2引数ではループ再生をするためTRUEを指定しています。

メインループではキーの処理を行い、キーが押された瞬間にドラムの音を鳴らすようにしています。

    while(1) {

            :

        BYTE key[256];
        GetKeyboardState( key );

        if( key[VK_ESCAPE]&0x80 )
            break;

        // オープンハイハット
        if( key['V']&0x80 ) {
            if( !bOn[0] ) {
                bOn[0] = TRUE;
                ds.Reset( 2 );
                ds.Play( 2 );
            }
        } else {
            bOn[0] = FALSE;
        }

        // クローズハイハット
        if( key['C']&0x80 ) {
            if( !bOn[1] ) {
                bOn[1] = TRUE;
                ds.Reset( 1 );
                ds.Play( 1 );
            }
        } else {
            bOn[1] = FALSE;
        }

        // スネア
        if( key['X']&0x80 ) {
            if( !bOn[2] ) {
                bOn[2] = TRUE;
                ds.Reset( 3 );
                ds.Play( 3 );
            }
        } else {
            bOn[2] = FALSE;
        }

        // バス
        if( key['Z']&0x80 ) {
            if( !bOn[3] ) {
                bOn[3] = TRUE;
                ds.Reset( 4 );
                ds.Play( 4 );
            }
        } else {
            bOn[3] = FALSE;
        }

        Sleep(3);
    }

bOn変数はキーが押された瞬間を把握するための変数です。
これはキーが押されるとTRUEとなり離されるとFALSEになるように制御しますが、
この処理を詳しく説明すると、まずキーを押した瞬間はまだFALSEであるため、
この時キーが押された瞬間と判断して音を出します。
そして同時にこの変数をTRUEにすることで次のフレームでまだキーが押されている場合は、
この変数はTRUEとなっているため押された瞬間では無いとして何も行いません。
その後キーが離されたらこの変数をFALSEにすることで、
再びキーが押された瞬間を認識することが出来るようになります。

ESCや×ボタンにてソフトを終了しようとするとこのループを抜けるので、
最後にライブラリやCOMの終了処理、ウィンドウの削除を呼び出して終わります。

    ds.Delete();

    // COMの終了
    CoUninitialize();

    win.Delete();

    return 0;
}



このようにCDSProライブラリを使用すれば特に何も考えずに簡単にサウンドの再生が行えます。

またもしiOSやAndroid(NDK)などでサウンド再生を行う場合は、その都度サウンドのロード処理を書くのではなく、
このライブラリを参考にOSにあったラッパーライブラリを作っておくことで、
クロスプラットフォームなプログラミングが出来るようになります。