カクタスソフトウェア
カクタスソフトウェア
サウンド MIDI マルチメディア アプリケーション

再生デバイスの列挙とオブジェクト生成

演奏させたいデバイスを指定するときや、デバイスの機能を調べる必要がある場合、デバイスの列挙を行います。デフォルトのデバイスで良いときは、デバイスの列挙を省略することができます。

次にダイレクトサウンド再生オブジェクトを作成します。これは再生を担当する本体にあたるものです。このオブジェクトはどのデバイスで再生するかを識別し、ミックスダウンされたサウンドを格納するプライマリーバッファを自動的に作成します。

再生デバイスの列挙

ダイレクトサウンドの再生デバイスを列挙するには、DirectSoundEnumerate()関数を用います。

HRESULT WINAPI DirectSoundEnumerate(
    LPDSENUMCALLBACK    pDSEnumCallback,        // コールバック関数のアドレス
    LPVOID              pContext);              // ユーザー引数

デバイス情報を得るためのコールバック関数をpDSEnumCallbackに設定します。pContextは必要に応じてインスタンスのアドレスなどを設定します。コールバック関数の仕様は録音デバイスの列挙を行う関数と同じです。

INT_PTR CALLBACK DSoundEnumCallback(
    GUID*       pGUID,                          // デバイスのGUID
    LPSTR       strDesc,                        // デバイス名
    LPSTR       strDrvName,                     // ドライバー名
    VOID*       pContext);                      // ユーザー引数

DSoundEnumCallback()関数は、デバイスの数だけ呼び出されます。最初に「プライマリサウンドドライバ」が戻り、続けてインストールされているデバイスが戻ります。

プライマリサウンドドライバの時は、pGUIDはNULLになります。GUIDの保存はディープコピーで行わなければなりません。つまり、pGUIDポインターを保存するのではなく、別途GUID構造体をアロケートしそこへpGUIDの内容をコピーします。コンボボックスにデバイス名を表示する時などは、strDescを用います。

以下にコンボボックスにデバイスの列挙を実装した例を示します。InitComboBox()でデバイスの列挙を行い、ExitComboBox()でGUID構造体を破棄しています。

void CCmbDevOut::InitComboBox(void)
{
    DirectSoundEnumerate((LPDSENUMCALLBACK)DSoundEnumCallback, (VOID*)this);
    SetCurSel(0);
}
void CCmbDevOut::ExitComboBox(void)
{
    for (int i=0; i<m_ptrArray.GetCount(); i++)
    {
        GUID* pDevGUID = (GUID*)m_ptrArray[i];
        SAFE_DELETE(pDevGUID);
    }
    m_ptrArray.RemoveAll();
}
INT_PTR CALLBACK CCmbDevOut::DSoundEnumCallback(
    GUID*       pGUID,
    LPSTR       strDesc,
    LPSTR       strDrvName,
    VOID*       pContext)
{
    CCmbDevOut* pCmbDevOut = (CCmbDevOut*)pContext;
    pCmbDevOut->AddString((LPCTSTR)strDesc);
    GUID* pDevGUID = NULL;

    if (pGUID)
    {
        pDevGUID = new GUID;
        CopyMemory(pDevGUID, pGUID, sizeof(GUID));
    }
    pCmbDevOut->m_ptrArray.Add(pDevGUID);

    return true;
}

再生オブジェクトの作成

DirectSoundCreate8()関数を用いてダイレクトサウンド再生オブジェクトを作成します。このオブジェクトによって再生デバイスを識別します。

HRESULT WINAPI DirectSoundCreate8(
    LPCGUID             pcGuidDevice,
    LPDIRECTSOUND8*     ppDS8,  
    LPUNKNOWN           pUnkOuter)

第1引数に再生デバイスを示すGUIDを設定します。このGUIDはDirectSoundEnumerate()関数を用いて取得したものです。デフォルトデバイスで良い時は、GUID_NULLを指定します。第2引数にIDirectSound8インターフェースへのポインター、第3引数はNULLと します。IDirectSound8インターフェースは、バッファオブジェクトの作成やデバイスの管理、環境の設定などに用います。

ダイレクトサウンドでは一つの再生デバイスを複数のアプリケーションから利用することを許可しています。これによってデバイスの取り合いが起こりますが、SetCooperativeLevel()関数でどのようにデバイスを利用し合うか調整します。

HRESULT SetCooperativeLevel(
    HWND        hwnd,
    DWORD       dwLevel)

hWndはアプリケーションのメインウィンドウのハンドルです。dwLevelの詳細を以下に示します。

dwLevel 説明 コメント
DSSCL_NORMAL ウェーブのスペックを落とし、互換性を高めた仕様。 サウンドの質より確実な再生を期待する場合用いる。
DSSCL_PRIORITY 任意のウェーブフォーマットを設定できる。 機能と制限のバランスが良い。通常この設定を用いる。
DSSCL_WRITEPRIMARY プライマリーバッファへの書き込みを許可する。 デバイスの性能をぎりぎりまで引き出すことができる。特別な用途以外用いない方が良い。

以下に再生オブジェクトの作成例を示します。

HRESULT SoundDevice::CreateObject(
    LPCGUID     pcGuidDevice,
    HWND        hWnd,
    DWORD       dwCoopLevel)
{
HRESULT hr;

    SAFE_RELEASE(m_pDirectSound8);

    hr = DirectSoundCreate8(pcGuidDevice, &m_pDirectSound8, NULL);
    if (FAILED(hr))         return hr;

    hr = m_pDirectSound->SetCooperativeLevel(hWnd, dwCoopLevel);
    if (FAILED(hr))         return hr;

    return S_OK;
}

再生オブジェクトは特定の再生デバイスに関連付けれらています。そのためデバイスを変更するときは、古いオブジェクトを破棄し新しいオブジェクトを作り直さなければなりません。

ドキュメントの先頭へ

カクタスソフトウェア 技術協力 資料室 資料室の広場 SourceForge.jp お問い合わせ