ようにしなきゃなんて気が湧いてきて、頼まれてもいないのに関数・変数名を
主体に一新しました。
DS8.h
► スポイラーを表示
//***********************************************************
// DS8.h for Windows application 2017.12.15 by V30
//***********************************************************
#pragma once
#include
#include
#include
#include
#pragma comment(lib, "dsound.lib")
//DS8名前空間
namespace DS8
{
using namespace ::Microsoft::WRL;
using namespace ::std;
//DSデバイスインスタンス構造体
struct DSDEVICEINSTANCE
{
LPGUID guid; //GUID
LPCTSTR desc; //Description
LPCTSTR name; //Module Name
//コンストラクタ
DSDEVICEINSTANCE(LPGUID guid = nullptr, LPCTSTR desc = nullptr, LPCTSTR name = nullptr);
};
//DSデバイスインスタンス列挙コールバック
BOOL CALLBACK DSDeviceInstanceEnumerateCallback(LPGUID guid, LPCTSTR desc, LPCTSTR name, LPVOID context);
//DS8デバイスインターフェイス作成
HRESULT CreateDS8Device(const HWND &window, ComPtr &ds8device, LPCGUID guid = NULL, const DWORD &cooperativelevel = DSSCL_PRIORITY);
ComPtr CreateDS8Device(const HWND &window, LPCGUID guid = NULL, const DWORD &cooperativelevel = DSSCL_PRIORITY);
//DS8デバイスインターフェイス配列作成
size_t CreateDS8DeviceArray(const HWND &window, const vector &guidarray, vector> &ds8devicearray, const DWORD &cooperativelevel = DSSCL_PRIORITY);
vector> CreateDS8DeviceArray(const HWND &window, const vector &guidarray, const DWORD &cooperativelevel = DSSCL_PRIORITY);
//DSプライマリバッファインターフェイス作成
HRESULT CreateDSBuffer(const ComPtr &ds8device, const DSBUFFERDESC &dsbdesc, ComPtr &dsbuffer);
ComPtr CreateDSBuffer(const ComPtr &ds8device, const DSBUFFERDESC &dsbdesc);
//DSセカンダリバッファインターフェイス作成
HRESULT CreateDSBuffer8(const ComPtr &dsbuffer, ComPtr &dsbuffer8);
ComPtr CreateDSBuffer8(const ComPtr &dsbuffer);
//DSデバイスインスタンス列挙
size_t EnumerateDSDeviceInstance(vector &dsdeviceinstancearray);
vector EnumerateDSDeviceInstance();
//DSバッファ波形データロード
HRESULT LoadWaveDataIntoDSBuffer(const ComPtr &buffer, const DWORD &bufferoffset, const BYTE *wavedata, const DWORD &length);
HRESULT LoadWaveDataIntoDSBuffer(const ComPtr &buffer, const DWORD &bufferoffset, const unique_ptr &wavedata, const DWORD &length);
HRESULT LoadWaveDataIntoDSBuffer(const ComPtr &buffer, const DWORD &bufferoffset, const vector &wavedata, const DWORD &length = 0);
//DS8キャプチャデバイスインターフェイス作成
HRESULT CreateDS8CaptureDevice(const HWND &window, ComPtr &ds8capturedevice, LPCGUID guid = NULL);
ComPtr CreateDS8CaptureDevice(const HWND &window, LPCGUID guid = NULL);
//DS8キャプチャデバイスインターフェイス配列作成
size_t CreateDS8CaptureDeviceArray(const HWND &window, const vector &guidarray, vector> &ds8capturedevicearray);
vector> CreateDS8CaptureDeviceArray(const HWND &window, const vector &guidarray);
//DSプライマリキャプチャバッファインターフェイス作成
HRESULT CreateDSCaptureBuffer(const ComPtr &ds8device, const DSCBUFFERDESC &dscbdesc, ComPtr &dscapturebuffer);
ComPtr CreateDSCaptureBuffer(const ComPtr &ds8device, const DSCBUFFERDESC &dscbdesc);
//DS8セカンダリキャプチャバッファインターフェイス作成
HRESULT CreateDSCaptureBuffer8(const ComPtr &dscapturebuffer, ComPtr &dscapturebuffer8);
ComPtr CreateDSCaptureBuffer8(const ComPtr &dscapturebuffer);
//DSキャプチャデバイスインスタンス列挙
size_t EnumerateDSCaptureDeviceInstance(vector &dsdeviceinstancearray);
vector EnumerateDSCaptureDeviceInstance();
//DS通知インターフェイス作成
HRESULT CreateDSNotify(const ComPtr &dsbuffer, ComPtr &dsnotify);
ComPtr CreateDSNotify(const ComPtr &dsbuffer);
}
► スポイラーを表示
#include
namespace DS8
{
DSDEVICEINSTANCE::DSDEVICEINSTANCE(LPGUID guid, LPCTSTR desc, LPCTSTR name) :
guid(guid), //GUID
desc(desc), //Description
name(name) //Module Name
{}
BOOL CALLBACK DSDeviceInstanceEnumerateCallback(LPGUID guid, LPCTSTR desc, LPCTSTR name, LPVOID context)
{
((vector*)context)->push_back(DSDEVICEINSTANCE(guid, desc, name)); //列挙デバイス保存
return TRUE; //デバイス列挙継続
}
HRESULT CreateDS8Device(const HWND &window, ComPtr &ds8device, LPCGUID guid, const DWORD &cooperativelevel)
{
ComPtr ds8; //DS8デバイス
HRESULT hr(DirectSoundCreate8(guid, &ds8, NULL)); //DS8デバイス作成
if SUCCEEDED(hr) hr = ds8->SetCooperativeLevel(window, cooperativelevel); //協調レベル設定
if SUCCEEDED(hr) ds8device.Swap(ds8); //引数とスワップ
return hr; //結果返還
}
ComPtr CreateDS8Device(const HWND &window, LPCGUID guid, const DWORD &cooperativelevel)
{
ComPtr ds8; //DS8デバイス
HRESULT hr(DirectSoundCreate8(guid, &ds8, NULL)); //DS8デバイス作成
if SUCCEEDED(hr) hr = ds8->SetCooperativeLevel(window, cooperativelevel); //協調レベル設定
return ds8; //結果返還
}
size_t CreateDS8DeviceArray(const HWND &window, const vector &guidarray, vector> &ds8devicearray, const DWORD &cooperativelevel)
{
ComPtr ds8; //DS8デバイス
vector> ds8array; //DS8デバイス配列
size_t creationsize(0); //デバイス作成数
HRESULT hr(E_FAIL); //結果
for (size_t i(0), j(guidarray.size()); i SetCooperativeLevel(window, DSSCL_PRIORITY); //協調レベル設定
if SUCCEEDED(hr) ds8array.push_back(ds8); //要素追加
}
if (creationsize = ds8array.size()) ds8devicearray.swap(ds8array); //データスワップ
return creationsize; //デバイス作成数返還
}
vector> CreateDS8DeviceArray(const HWND &window, const vector &guidarray, const DWORD &cooperativelevel)
{
ComPtr ds8; //DS8デバイス
vector> ds8array; //DS8デバイス配列
HRESULT hr(E_FAIL); //結果
for (size_t i(0); i SetCooperativeLevel(window, DSSCL_PRIORITY); //協調レベル設定
if SUCCEEDED(hr) ds8array.push_back(ds8); //要素追加
}
return ds8array; //DS8デバイス配列返還
}
HRESULT CreateDSBuffer(const ComPtr &ds8device, const DSBUFFERDESC &dsbdesc, ComPtr &dsbuffer)
{
if (!ds8device.Get() || dsbdesc.dwBufferBytes DSBSIZE_MAX) return E_FAIL; //引数チェック
ComPtr primery; //プライマリバッファ
HRESULT hr(ds8device->CreateSoundBuffer(&dsbdesc, &primery, NULL)); //プライマリバッファ作成
if SUCCEEDED(hr) dsbuffer.Swap(primery); //引数とスワップ
return hr; //結果返還
}
ComPtr CreateDSBuffer(const ComPtr &ds8device, const DSBUFFERDESC &dsbdesc)
{
if (!ds8device.Get() || dsbdesc.dwBufferBytes DSBSIZE_MAX) return nullptr; //引数チェック
ComPtr primery; //プライマリバッファ
HRESULT hr(ds8device->CreateSoundBuffer(&dsbdesc, &primery, NULL)); //プライマリバッファ作成
return primery; //結果返還
}
HRESULT CreateDSBuffer8(const ComPtr &dsbuffer, ComPtr &dsbuffer8)
{
if (!dsbuffer.Get()) return E_FAIL; //引数チェック
ComPtr secondary; //セカンダリバッファ
HRESULT hr(dsbuffer->QueryInterface(IID_IDirectSoundBuffer8, &secondary)); //セカンダリバッファ作成
if SUCCEEDED(hr) dsbuffer8.Swap(secondary); //引数とスワップ
return hr; //結果返還
}
ComPtr CreateDSBuffer8(const ComPtr &dsbuffer)
{
ComPtr secondary; //セカンダリバッファ
if (dsbuffer.Get()) dsbuffer->QueryInterface(IID_IDirectSoundBuffer8, &secondary); //引数チェック&セカンダリバッファ作成
return secondary; //結果返還
}
size_t EnumerateDSDeviceInstance(vector &dsdeviceinstancearray)
{
vector dsdiarray; //DSデバイスインスタンス配列
size_t enumsize(0); //列挙サイズ
DirectSoundEnumerate(DSDeviceInstanceEnumerateCallback, (LPVOID)&dsdiarray); //DSデバイスインスタンス列挙コールバック
if (enumsize = dsdiarray.size()) dsdeviceinstancearray.swap(dsdiarray); //引数とスワップ
return enumsize; //列挙サイズ返還
}
vector EnumerateDSDeviceInstance()
{
vector dsdiarray; //DSデバイスインスタンス配列
DirectSoundEnumerate(DSDeviceInstanceEnumerateCallback, (LPVOID)&dsdiarray); //DSデバイスインスタンス列挙コールバック
return dsdiarray; //DSデバイスインスタンス列挙配列返還
}
HRESULT LoadWaveDataIntoDSBuffer(const ComPtr &buffer, const DWORD &bufferoffset, const BYTE *wavedata, const DWORD &length)
{
if (!buffer.Get() || !wavedata) return E_FAIL; //引数チェック
DWORD length_1(0); //波形データ書き込みサイズ1
DWORD length_2(0); //波形データ書き込みサイズ2
LPVOID offset_1(nullptr); //波形データ書き込み位置1
LPVOID offset_2(nullptr); //波形データ書き込み位置2
HRESULT hr(buffer->Lock(bufferoffset, length, &offset_1, &length_1, &offset_2, &length_2, NULL)); //ロック
if (hr == DSERR_BUFFERLOST)
{
hr = buffer->Restore(); //復元
if SUCCEEDED(hr) hr = buffer->Lock(bufferoffset, length, &offset_1, &length_1, &offset_2, &length_2, NULL); //ロック
}
if SUCCEEDED(hr)
{
if (offset_1) memcpy(offset_1, wavedata , length_1); //波形データ書き込み1
if (offset_2) memcpy(offset_2, wavedata + length_1 , length_2); //波形データ書き込み2
hr = buffer->Unlock(offset_1, length_1, offset_2, length_2); //ロック解除
}
return hr; //結果返還
}
HRESULT LoadWaveDataIntoDSBuffer(const ComPtr &buffer, const DWORD &bufferoffset, const unique_ptr &wavedata, const DWORD &length)
{
if (!buffer.Get() || !wavedata) return E_FAIL; //引数チェック
DWORD length_1(0); //波形データ書き込みサイズ1
DWORD length_2(0); //波形データ書き込みサイズ2
LPVOID offset_1(nullptr); //波形データ書き込み位置1
LPVOID offset_2(nullptr); //波形データ書き込み位置2
HRESULT hr(buffer->Lock(bufferoffset, length, &offset_1, &length_1, &offset_2, &length_2, NULL)); //ロック
if (hr == DSERR_BUFFERLOST)
{
hr = buffer->Restore(); //復元
if SUCCEEDED(hr) hr = buffer->Lock(bufferoffset, length, &offset_1, &length_1, &offset_2, &length_2, NULL); //ロック
}
if SUCCEEDED(hr)
{
if (offset_1) memcpy(offset_1, wavedata.get() , length_1); //波形データ書き込み1
if (offset_2) memcpy(offset_2, wavedata.get() + length_1, length_2); //波形データ書き込み2
hr = buffer->Unlock(offset_1, length_1, offset_2, length_2); //ロック解除
}
return hr; //結果返還
}
HRESULT LoadWaveDataIntoDSBuffer(const ComPtr &buffer, const DWORD &bufferoffset, const vector &wavedata, const DWORD &length)
{
if (!buffer.Get() || wavedata.empty()) return E_FAIL; //引数チェック
DWORD length_0(length); //波形データ書き込みサイズ1
DWORD length_1(0); //波形データ書き込みサイズ1
DWORD length_2(0); //波形データ書き込みサイズ2
LPVOID offset_1(nullptr); //波形データ書き込み位置1
LPVOID offset_2(nullptr); //波形データ書き込み位置2
if (length == 0 || (size_t)length > wavedata.size()) length_0 = wavedata.size();
HRESULT hr(buffer->Lock(bufferoffset, length_0, &offset_1, &length_1, &offset_2, &length_2, NULL)); //ロック
if (hr == DSERR_BUFFERLOST)
{
hr = buffer->Restore(); //復元
if SUCCEEDED(hr) hr = buffer->Lock(bufferoffset, length_0, &offset_1, &length_1, &offset_2, &length_2, NULL); //ロック
}
if SUCCEEDED(hr)
{
if (offset_1) memcpy(offset_1, wavedata.data() , length_1); //波形データ書き込み1
if (offset_2) memcpy(offset_2, wavedata.data() + length_1 , length_2); //波形データ書き込み2
hr = buffer->Unlock(offset_1, length_1, offset_2, length_2); //ロック解除
}
return hr; //結果返還
}
HRESULT CreateDS8CaptureDevice(const HWND &window, ComPtr &ds8capturedevice, LPCGUID guid)
{
ComPtr dsc8; //DS8キャプチャデバイス
HRESULT hr(DirectSoundCaptureCreate8(guid, &dsc8, NULL)); //DS8キャプチャデバイス作成
if SUCCEEDED(hr) ds8capturedevice.Swap(dsc8); //引数とスワップ
return hr; //結果返還
}
ComPtr CreateDS8CaptureDevice(const HWND &window, LPCGUID guid)
{
ComPtr dsc8; //DS8キャプチャデバイス
HRESULT hr(DirectSoundCaptureCreate8(guid, &dsc8, NULL)); //DS8キャプチャデバイス作成
return dsc8; //結果返還
}
size_t CreateDS8CaptureDeviceArray(const HWND &window, const vector &guidarray, vector> &ds8capturedevicearray)
{
ComPtr dsc8; //DS8キャプチャデバイス
vector> dsc8array; //DS8キャプチャデバイス配列
size_t creationsize(0); //デバイス作成数
HRESULT hr(E_FAIL); //結果
for (size_t i(0), j(guidarray.size()); i > CreateDS8CaptureDeviceArray(const HWND &window, const vector &guidarray)
{
ComPtr dsc8; //DS8キャプチャデバイス
vector> dsc8array; //DS8キャプチャデバイス配列
HRESULT hr(E_FAIL); //結果
for (size_t i(0); i &ds8device, const DSCBUFFERDESC &dscbdesc, ComPtr &dscapturebuffer)
{
if (!ds8device.Get() || dscbdesc.dwBufferBytes DSBSIZE_MAX) return E_FAIL; //引数チェック
ComPtr primery; //プライマリバッファ
HRESULT hr(ds8device->CreateCaptureBuffer(&dscbdesc, &primery, NULL)); //プライマリバッファ作成
if SUCCEEDED(hr) dscapturebuffer.Swap(primery); //引数とスワップ
return hr; //結果返還
}
ComPtr CreateDSCaptureBuffer(const ComPtr &ds8device, const DSCBUFFERDESC &dscbdesc)
{
if (!ds8device.Get() || dscbdesc.dwBufferBytes DSBSIZE_MAX) return nullptr; //引数チェック
ComPtr primery; //プライマリバッファ
HRESULT hr(ds8device->CreateCaptureBuffer(&dscbdesc, &primery, NULL)); //プライマリバッファ作成
return primery; //結果返還
}
HRESULT CreateDSCaptureBuffer8(const ComPtr &dscapturebuffer, ComPtr &dscapturebuffer8)
{
if (!dscapturebuffer.Get()) return E_FAIL; //引数チェック
ComPtr secondary; //セカンダリバッファ
HRESULT hr(dscapturebuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8, &secondary)); //セカンダリバッファ作成
if SUCCEEDED(hr) dscapturebuffer8.Swap(secondary); //引数とスワップ
return hr; //結果返還
}
ComPtr CreateDSCaptureBuffer8(const ComPtr &dscapturebuffer)
{
ComPtr secondary; //セカンダリバッファ
if (dscapturebuffer.Get()) dscapturebuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8, &secondary); //引数チェック&セカンダリバッファ作成
return secondary; //結果返還
}
size_t EnumerateDSCaptureDeviceInstance(vector &dsdeviceinstancearray)
{
vector dsdiarray; //DSデバイスインスタンス配列
size_t enumsize(0); //列挙サイズ
DirectSoundCaptureEnumerate(DSDeviceInstanceEnumerateCallback, (LPVOID)&dsdiarray); //DSデバイスインスタンス列挙コールバック
if (enumsize = dsdiarray.size()) dsdeviceinstancearray.swap(dsdiarray); //引数とスワップ
return enumsize; //列挙サイズ返還
}
vector EnumerateDSCaptureDeviceInstance()
{
vector dscdiarray; //DSキャプチャデバイスインスタンス配列
DirectSoundCaptureEnumerate(DSDeviceInstanceEnumerateCallback, (LPVOID)&dscdiarray); //DSキャプチャデバイスインスタンス列挙コールバック
return dscdiarray; //DSキャプチャデバイスインスタンス列挙配列返還
}
HRESULT CreateDSNotify(const ComPtr &dsbuffer, ComPtr &dsnotify)
{
if (!dsbuffer.Get()) return E_FAIL; //引数チェック
ComPtr notify; //通知インターフェイス
HRESULT hr(dsbuffer->QueryInterface(IID_IDirectSoundNotify, ¬ify)); //通知インターフェイス作成
if SUCCEEDED(hr) dsnotify.Swap(notify); //引数とスワップ
return hr; //結果返還
}
ComPtr CreateDSNotify(const ComPtr &dsbuffer)
{
ComPtr notify; //通知インターフェイス
if (dsbuffer.Get()) dsbuffer->QueryInterface(IID_IDirectSoundNotify, ¬ify); //引数チェック&通知インターフェイス作成
return notify; //結果返還
}
}
今まで散々載っけておいて、今更感ありありかな?
因みに、動作確認0なので、動作保証も0です。
[English]
まぁ自分は、英語力=中学生程度の超典型的な昭和の凡人なので、こんなもんで
上出来でしょう。
[Notation]
MSDN主体で勉強している割にMicrosoft標準のハンガリアン記法じゃないのは、
別にハンガリアン嫌いな人もよろしくって意味はありません。
自己の流儀はハンガリアン系なのですが、グローバル変数やクラスのメンバ変数
以外の変数は、小文字と数字だけにしています。
[Result]
かなり汎用的になり、原型(関数内の処理)に近くなってしまいました。
でも、お陰で関数・変数・インターフェイスのネーミングがその場凌ぎのいい
加減なものだったのが判明しました。ベースがDS初心者頃の物なんで。
とにかく、音楽再生の基本セットは揃いました。
ノーマル再生・無限ループ再生は、これで十分可能です。
バッファ内の特定区間・位置でのループ・停止処理は、通知インターフェイスを
使うか、ストリームバッファを自作してどうにかこうにかするのが常套です。
後者を使用しておりますので、前者は勉強不足で今だによく理解しておりません。
ファイルからの再生形式&波形データロードは、mmio使えば自作しなくても楽チン
ですが、自分の場合は音楽ファイルの規格やファイル構造を学んで1からクラスを
作りました。
自作クラスは、チャンクの読み込み・書き込みがイマイチなコーディングなので、
臨機応変にチャンク脱着できるように作り直している最中です。
プレイヤーは危なげながらも何とか作れる様になっているので、次はレコーダーに
挑戦してみようと思います。
カラオケの採点なんか出来たら凄いなぁなんて、夢のまた夢です。
とりあえずは、この2ファイルにDS(DirectSound)キャプチャインターフェイス関連
の初期化関数を追加する予定です。
本題のまともなゲームを作る前に、システム作りだけで何年も掛かりそうだ。。。