• R/O
  • HTTP
  • SSH
  • HTTPS

wasapi2: Commit

wasapiを実験するプロジェクトです。


Commit MetaInfo

Revision011ed27321a656dad22a365eacc9ee2f6709fbe1 (tree)
Time2012-10-30 04:24:23
Authorsfpg <sfpg@user...>
Commitersfpg

Log Message

Change Summary

Incremental Difference

--- a/.gitignore
+++ b/.gitignore
@@ -11,4 +11,5 @@ unix/
1111 Debug/
1212 Release/
1313 ipch/
14-sidplay2/
\ No newline at end of file
14+sidplay2/
15+backup/
\ No newline at end of file
--- a/wasapi2/config_tab_dialog.cpp
+++ b/wasapi2/config_tab_dialog.cpp
@@ -58,7 +58,7 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
5858 namespace sf
5959 {
6060 config_tab_dialog::config_tab_dialog(sf::base_window& parent_window,HWND tab_hwnd,int tab_id,const std::wstring& menu_name,const std::wstring& name,HINSTANCE inst,LPCTSTR temp)
61- : tab_dialog_base(parent_window,tab_hwnd,tab_id,menu_name,name,inst,temp)
61+ : tab_dialog_base(parent_window,tab_hwnd,tab_id,menu_name,name,inst,temp),current_output_driver_index_(-1),current_input_driver_index_(-1)
6262 ,update_config_dialog_(false)
6363 ,edit_output_config_(false)
6464 ,edit_input_config_(false)
@@ -359,7 +359,7 @@ namespace sf
359359
360360 for(int c = 0;c < i.size();++c)
361361 {
362- if(i[c].is_selected){
362+ if(i[c].is_selected_){
363363 current_output_driver_index_ = c;
364364 }
365365 }
@@ -371,10 +371,13 @@ namespace sf
371371 wasapi_device_manager::device_infos_t& i(m->input_device_infos());
372372 for(int c = 0;c < i.size();++c)
373373 {
374- if(i[c].is_selected){
374+ if(i[c].is_selected_){
375375 current_input_driver_index_ = c;
376376 }
377377 }
378+// if(!i.empty() || current_input_driver_index_ == -1)
379+// {
380+// }
378381 }
379382 edit_output_config_ = false;
380383 edit_input_config_ = false;
@@ -407,7 +410,7 @@ namespace sf
407410
408411 for(int c = 0,e = i.size(); c < e;++c)
409412 {
410- SendMessage(hwnd_endp,CB_ADDSTRING,0,(LPARAM)i[c].device_friendly_name.c_str());
413+ SendMessage(hwnd_endp,CB_ADDSTRING,0,(LPARAM)i[c].display_name_.c_str());
411414 SendMessage(hwnd_endp,CB_SETITEMDATA,c,c);
412415 if(c == current_output_driver_index_)
413416 {
@@ -416,7 +419,7 @@ namespace sf
416419 }
417420
418421 typedef wasapi_device_manager::format_map_type fmts_t;
419- fmts_t& fmts = i[current_output_driver_index_].support_formats;
422+ fmts_t& fmts = i[current_output_driver_index_].support_formats_;
420423 ////
421424 HWND hwnd_smp_bits = GetDlgItem(hwnd_,IDC_SAMPLE_BIT);
422425
@@ -526,8 +529,8 @@ namespace sf
526529 // ----------------------------------------
527530 SetDlgItemInt(hwnd_,IDC_LATENCY,editing_output_params_.latency/10000,TRUE);
528531 SetDlgItemText(hwnd_,IDC_MIN_MAX_LATENCY,(boost::wformat(L"(%dms ~ %dms)")
529- % (i[current_output_driver_index_].latency_minimum / 10000)
530- % (i[current_output_driver_index_].latency_default / 10000)).str().c_str());
532+ % (i[current_output_driver_index_].latency_minimum_ / 10000)
533+ % (i[current_output_driver_index_].latency_default_ / 10000)).str().c_str());
531534 } // 出力ダイアログ
532535
533536 // ===================================================================
@@ -541,7 +544,7 @@ namespace sf
541544
542545 for(int c = 0,e = i.size(); c < e;++c)
543546 {
544- SendMessage(hwnd_endp,CB_ADDSTRING,0,(LPARAM)i[c].device_friendly_name.c_str());
547+ SendMessage(hwnd_endp,CB_ADDSTRING,0,(LPARAM)i[c].display_name_.c_str());
545548 SendMessage(hwnd_endp,CB_SETITEMDATA,c,c);
546549 if(c == current_input_driver_index_)
547550 {
@@ -550,7 +553,7 @@ namespace sf
550553 }
551554
552555 typedef wasapi_device_manager::format_map_type fmts_t;
553- fmts_t& fmts = i[current_input_driver_index_].support_formats;
556+ fmts_t& fmts = i[current_input_driver_index_].support_formats_;
554557 ////
555558 HWND hwnd_smp_bits = GetDlgItem(hwnd_,IDC_INPUT_SAMPLE_BIT);
556559
@@ -660,8 +663,8 @@ namespace sf
660663 // ----------------------------------------
661664 SetDlgItemInt(hwnd_,IDC_INPUT_LATENCY,editing_input_params_.latency/10000,TRUE);
662665 SetDlgItemText(hwnd_,IDC_INPUT_MIN_MAX_LATENCY,(boost::wformat(L"(%dms ~ %dms)")
663- % (i[current_input_driver_index_].latency_minimum / 10000)
664- % (i[current_input_driver_index_].latency_default / 10000)).str().c_str());
666+ % (i[current_input_driver_index_].latency_minimum_ / 10000)
667+ % (i[current_input_driver_index_].latency_default_ / 10000)).str().c_str());
665668 } // 入力ダイアログ
666669
667670 update_config_dialog_ = false;
--- a/wasapi2/icon.cpp
+++ b/wasapi2/icon.cpp
@@ -126,11 +126,11 @@ namespace sf {
126126 );
127127
128128 ID2D1DCRenderTargetPtr dcr;
129- throw_if_err<>()(factory->CreateDCRenderTarget(&props,&dcr));
129+ throw_if_err<>()(factory->CreateDCRenderTarget(&props,dcr.GetAddressOf()));
130130 RECT rect = {0,0,size.width,size.height};
131131 // 互換DCへのバインド
132132 throw_if_err<>()(dcr->BindDC(cdc.get(),&rect));
133- dcr->DrawBitmap(ptr);
133+ dcr->DrawBitmap(ptr.Get());
134134 }
135135 }
136136 icon(bmp,size.width,size.height);
--- a/wasapi2/info_tab_dialog.cpp
+++ b/wasapi2/info_tab_dialog.cpp
@@ -119,7 +119,7 @@ namespace sf
119119 THROW_IFERR(D2D1CreateFactory(
120120 D2D1_FACTORY_TYPE_SINGLE_THREADED,
121121 options,
122- &factory_
122+ factory_.GetAddressOf()
123123 ));
124124 #else
125125 THROW_IFERR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory_));
@@ -131,7 +131,7 @@ namespace sf
131131 THROW_IFERR(::DWriteCreateFactory(
132132 DWRITE_FACTORY_TYPE_SHARED,
133133 __uuidof(IDWriteFactory),
134- reinterpret_cast<IUnknown**>(&write_factory_)
134+ reinterpret_cast<IUnknown**>(write_factory_.GetAddressOf())
135135 ));
136136 }
137137
@@ -227,9 +227,9 @@ namespace sf
227227 render_target_->DrawTextW(
228228 m.c_str(),
229229 m.size(),
230- write_text_format_,
230+ write_text_format_.Get(),
231231 layout_rect_,
232- brush);
232+ brush.Get());
233233 // render_target_->PopAxisAlignedClip();
234234 THROW_IFERR(render_target_->EndDraw());
235235
--- a/wasapi2/seq_tab_dialog.cpp
+++ b/wasapi2/seq_tab_dialog.cpp
@@ -126,7 +126,7 @@ namespace sf
126126 THROW_IFERR(D2D1CreateFactory(
127127 D2D1_FACTORY_TYPE_SINGLE_THREADED,
128128 options,
129- &factory_
129+ factory_.GetAddressOf()
130130 ));
131131 #else
132132 THROW_IFERR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory_));
@@ -138,7 +138,7 @@ namespace sf
138138 THROW_IFERR(::DWriteCreateFactory(
139139 DWRITE_FACTORY_TYPE_SHARED,
140140 __uuidof(IDWriteFactory),
141- reinterpret_cast<IUnknown**>(&write_factory_)
141+ reinterpret_cast<IUnknown**>(write_factory_.GetAddressOf())
142142 ));
143143 }
144144
@@ -236,9 +236,9 @@ namespace sf
236236 render_target_->DrawTextW(
237237 m.c_str(),
238238 m.size(),
239- write_text_format_,
239+ write_text_format_.Get(),
240240 layout_rect_,
241- brush);
241+ brush.Get());
242242 // render_target_->PopAxisAlignedClip();
243243 THROW_IFERR(render_target_->EndDraw());
244244
--- a/wasapi2/sf_com.h
+++ b/wasapi2/sf_com.h
@@ -35,7 +35,7 @@ namespace sf
3535 {
3636 if(ptr)
3737 {
38- ptr.Release();
38+ ptr.Reset();
3939 }
4040 };
4141 enum com_init
--- a/wasapi2/sf_windows.cpp
+++ b/wasapi2/sf_windows.cpp
@@ -14,7 +14,16 @@
1414 #include "sf_windows.h"
1515 #include "exception.h"
1616
17-
17+//#pragma comment(lib,"dxerr.lib")
18+#pragma comment( lib, "dxguid.lib" )
19+#pragma comment( lib, "d3d11.lib" )
20+#pragma comment( lib, "D3DCompiler.lib" )
21+#pragma comment( lib, "DirectXTK.lib" )
22+#pragma comment( lib, "dxgi.lib" )
23+//#pragma comment( lib, "d3dx9.lib" )
24+#pragma comment( lib, "Shlwapi.lib" )
25+#pragma comment( lib, "DWMApi.lib" )
26+#pragma comment( lib,"msimg32.lib")
1827
1928 #define THROW_IFERR(hres) \
2029 if (FAILED(hres)) { throw sf::win32_error_exception(hres); }
@@ -24,11 +33,189 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
2433 #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
2534 #endif
2635 using namespace std;
36+using namespace DirectX;
2737
2838 namespace sf
2939 {
40+ HRESULT EnableBlurBehind(HWND hwnd)
41+ {
42+ HRESULT hr = S_OK;
43+
44+ //Create and populate the BlurBehind structre
45+ DWM_BLURBEHIND bb = {0};
46+ //Enable Blur Behind and Blur Region;
47+ bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
48+ bb.fEnable = true;
49+ bb.hRgnBlur = ::CreateRectRgn(-1,-1,0,0);
50+
51+ //Enable Blur Behind
52+ hr = DwmEnableBlurBehindWindow(hwnd, &bb);
53+ //BOOL allow_ncpaint = TRUE;
54+ //DwmSetWindowAttribute(hwnd,DWMWA_ALLOW_NCPAINT,&allow_ncpaint,sizeof(BOOL));
55+ //DWMNCRENDERINGPOLICY policy = DWMNCRP_ENABLED;
56+ //DwmSetWindowAttribute(hwnd,DWMWA_NCRENDERING_POLICY,&policy,sizeof(policy));
57+
58+
59+ //if (SUCCEEDED(hr))
60+ //{
61+ // //do more things
62+ //MARGINS mgn = {-1};
63+ //hr = DwmExtendFrameIntoClientArea( hwnd, &mgn );
64+ /* }*/
65+ return hr;
66+ }
67+
68+ // 汎用情報格納用
69+ struct mode_info
70+ {
71+ mode_info(const std::wstring& n,const std::wstring& d) : name(n),description(d) {}
72+ std::wstring name;
73+ std::wstring description;
74+ };
75+
76+ // ディスプレイモード
77+ struct display_mode
78+ {
79+ display_mode(const std::wstring& n,const std::wstring& d) : name(n),description(d) {}
80+ std::wstring name;
81+ std::wstring description;
82+ };
83+
84+ std::vector<mode_info> display_modes =
85+ boost::assign::list_of<mode_info>
86+ (L"DXGI_FORMAT_UNKNOWN",L"フォーマットが不明")
87+ (L"DXGI_FORMAT_R32G32B32A32_TYPELESS",L"4 成分、128 ビット型なしフォーマット 1")
88+ (L"DXGI_FORMAT_R32G32B32A32_FLOAT",L"4 成分、128 ビット浮動小数点フォーマット 1")
89+ (L"DXGI_FORMAT_R32G32B32A32_UINT",L"4 成分、128 ビット符号なし整数フォーマット 1")
90+ (L"DXGI_FORMAT_R32G32B32A32_SINT",L"4 成分、128 ビット符号付き整数フォーマット 1")
91+ (L"DXGI_FORMAT_R32G32B32_TYPELESS",L"3 成分、96 ビット型なしフォーマット")
92+ (L"DXGI_FORMAT_R32G32B32_FLOAT",L"3 成分、96 ビット浮動小数点フォーマット")
93+ (L"DXGI_FORMAT_R32G32B32_UINT",L"3 成分、96 ビット符号なし整数フォーマット")
94+ (L"DXGI_FORMAT_R32G32B32_SINT",L"3 成分、96 ビット符号付き整数フォーマット")
95+ (L"DXGI_FORMAT_R16G16B16A16_TYPELESS",L"4 成分、64 ビット型なしフォーマット")
96+ (L"DXGI_FORMAT_R16G16B16A16_FLOAT",L"4 成分、64 ビット浮動小数点フォーマット")
97+ (L"DXGI_FORMAT_R16G16B16A16_UNORM",L"4 成分、64 ビット符号なし整数フォーマット")
98+ (L"DXGI_FORMAT_R16G16B16A16_UINT",L"4 成分、64 ビット符号なし整数フォーマット")
99+ (L"DXGI_FORMAT_R16G16B16A16_SNORM",L"4 成分、64 ビット符号付き整数フォーマット")
100+ (L"DXGI_FORMAT_R16G16B16A16_SINT",L"4 成分、64 ビット符号付き整数フォーマット")
101+ (L"DXGI_FORMAT_R32G32_TYPELESS",L"2 成分、64 ビット型なしフォーマット")
102+ (L"DXGI_FORMAT_R32G32_FLOAT",L"2 成分、64 ビット浮動小数点フォーマット")
103+ (L"DXGI_FORMAT_R32G32_UINT",L"2 成分、64 ビット符号なし整数フォーマット")
104+ (L"DXGI_FORMAT_R32G32_SINT",L"2 成分、64 ビット符号付き整数フォーマット")
105+ (L"DXGI_FORMAT_R32G8X24_TYPELESS",L"2 成分、64 ビット型なしフォーマット")
106+ (L"DXGI_FORMAT_D32_FLOAT_S8X24_UINT",L"32 ビット浮動小数点成分、および 2 つの符号なし整数成分です (追加の 32 ビットを含む)。")
107+ (L"DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS",L"32 ビット浮動小数点成分、および 2 つの型なし成分です (追加の 32 ビットを含む)。")
108+ (L"DXGI_FORMAT_X32_TYPELESS_G8X24_UINT",L"32 ビット型なし成分、および 2 つの符号なし整数成分です (追加の 32 ビットを含む)。")
109+ (L"DXGI_FORMAT_R10G10B10A2_TYPELESS",L"4 成分、32 ビット型なしフォーマット")
110+ (L"DXGI_FORMAT_R10G10B10A2_UNORM",L"4 成分、32 ビット符号なし整数フォーマット")
111+ (L"DXGI_FORMAT_R10G10B10A2_UINT",L"4 成分、32 ビット符号なし整数フォーマット")
112+ (L"DXGI_FORMAT_R11G11B10_FLOAT",L"3 成分、32 ビット浮動小数点フォーマット")
113+ (L"DXGI_FORMAT_R8G8B8A8_TYPELESS",L"3 成分、32 ビット型なしフォーマット")
114+ (L"DXGI_FORMAT_R8G8B8A8_UNORM",L"4 成分、32 ビット符号なし整数フォーマット")
115+ (L"DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",L"4 成分、32 ビット符号なし正規化整数 sRGB フォーマット")
116+ (L"DXGI_FORMAT_R8G8B8A8_UINT",L"4 成分、32 ビット符号なし整数フォーマット")
117+ (L"DXGI_FORMAT_R8G8B8A8_SNORM",L"3 成分、32 ビット符号付き整数フォーマット")
118+ (L"DXGI_FORMAT_R8G8B8A8_SINT",L"3 成分、32 ビット符号付き整数フォーマット")
119+ (L"DXGI_FORMAT_R16G16_TYPELESS",L"2 成分、32 ビット型なしフォーマット")
120+ (L"DXGI_FORMAT_R16G16_FLOAT",L"2 成分、32 ビット浮動小数点フォーマット")
121+ (L"DXGI_FORMAT_R16G16_UNORM",L"2 成分、32 ビット符号なし整数フォーマット")
122+ (L"DXGI_FORMAT_R16G16_UINT",L"2 成分、32 ビット符号なし整数フォーマット")
123+ (L"DXGI_FORMAT_R16G16_SNORM",L"2 成分、32 ビット符号付き整数フォーマット")
124+ (L"DXGI_FORMAT_R16G16_SINT",L"2 成分、32 ビット符号付き整数フォーマット")
125+ (L"DXGI_FORMAT_R32_TYPELESS",L"1 成分、32 ビット型なしフォーマット")
126+ (L"DXGI_FORMAT_D32_FLOAT",L"1 成分、32 ビット浮動小数点フォーマット")
127+ (L"DXGI_FORMAT_R32_FLOAT",L"1 成分、32 ビット浮動小数点フォーマット")
128+ (L"DXGI_FORMAT_R32_UINT",L"1 成分、32 ビット符号なし整数フォーマット")
129+ (L"DXGI_FORMAT_R32_SINT",L"1 成分、32 ビット符号付き整数フォーマット")
130+ (L"DXGI_FORMAT_R24G8_TYPELESS",L"2 成分、32 ビット型なしフォーマット")
131+ (L"DXGI_FORMAT_D24_UNORM_S8_UINT",L"深度チャンネルに 24 ビット、ステンシル チャンネルに 8 ビットを使用する 32 ビット Z バッファー フォーマット")
132+ (L"DXGI_FORMAT_R24_UNORM_X8_TYPELESS",L"1 成分、24 ビット符号なし正規化整数と追加の型なし 8 ビットを含む、32 ビット フォーマット")
133+ (L"DXGI_FORMAT_X24_TYPELESS_G8_UINT",L"1 成分、24 ビット型なしフォーマットと追加の 8 ビット符号なし整数成分を含む、32 ビット フォーマット")
134+ (L"DXGI_FORMAT_R8G8_TYPELESS",L"2 成分、16 ビット型なしフォーマット")
135+ (L"DXGI_FORMAT_R8G8_UNORM",L"2 成分、16 ビット符号なし整数フォーマット")
136+ (L"DXGI_FORMAT_R8G8_UINT",L"2 成分、16 ビット符号なし整数フォーマット")
137+ (L"DXGI_FORMAT_R8G8_SNORM",L"2 成分、16 ビット符号付き整数フォーマット")
138+ (L"DXGI_FORMAT_R8G8_SINT",L"2 成分、16 ビット符号付き整数フォーマット")
139+ (L"DXGI_FORMAT_R16_TYPELESS",L"1 成分、16 ビット型なしフォーマット")
140+ (L"DXGI_FORMAT_R16_FLOAT",L"1 成分、16 ビット浮動小数点フォーマット")
141+ (L"DXGI_FORMAT_D16_UNORM",L"1 成分、16 ビット符号なし正規化整数フォーマット")
142+ (L"DXGI_FORMAT_R16_UNORM",L"1 成分、16 ビット符号なし整数フォーマット")
143+ (L"DXGI_FORMAT_R16_UINT",L"1 成分、16 ビット符号なし整数フォーマット")
144+ (L"DXGI_FORMAT_R16_SNORM",L"1 成分、16 ビット符号付き整数フォーマット")
145+ (L"DXGI_FORMAT_R16_SINT",L"1 成分、16 ビット符号付き整数フォーマット")
146+ (L"DXGI_FORMAT_R8_TYPELESS",L"1 成分、8 ビット型なしフォーマット")
147+ (L"DXGI_FORMAT_R8_UNORM",L"1 成分、8 ビット符号なし整数フォーマット")
148+ (L"DXGI_FORMAT_R8_UINT",L"1 成分、8 ビット符号なし整数フォーマット")
149+ (L"DXGI_FORMAT_R8_SNORM",L"1 成分、8 ビット符号付き整数フォーマット")
150+ (L"DXGI_FORMAT_R8_SINT",L"1 成分、8 ビット符号付き整数フォーマット")
151+ (L"DXGI_FORMAT_A8_UNORM",L"1 成分、8 ビット符号なし整数フォーマット")
152+ (L"DXGI_FORMAT_R1_UNORM",L"1 成分、1 ビット符号なし正規化整数フォーマット 2.")
153+ (L"DXGI_FORMAT_R9G9B9E5_SHAREDEXP",L"4 成分、32 ビット浮動小数点フォーマット 2.")
154+ (L"DXGI_FORMAT_R8G8_B8G8_UNORM",L"4 成分、32 ビット符号なし正規化整数フォーマット 3")
155+ (L"DXGI_FORMAT_G8R8_G8B8_UNORM",L"4 成分、32 ビット符号なし正規化整数フォーマット 3")
156+ (L"DXGI_FORMAT_BC1_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
157+ (L"DXGI_FORMAT_BC1_UNORM",L"4 成分、ブロック圧縮フォーマット")
158+ (L"DXGI_FORMAT_BC1_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
159+ (L"DXGI_FORMAT_BC2_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
160+ (L"DXGI_FORMAT_BC2_UNORM",L"4 成分、ブロック圧縮フォーマット")
161+ (L"DXGI_FORMAT_BC2_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
162+ (L"DXGI_FORMAT_BC3_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
163+ (L"DXGI_FORMAT_BC3_UNORM",L"4 成分、ブロック圧縮フォーマット")
164+ (L"DXGI_FORMAT_BC3_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
165+ (L"DXGI_FORMAT_BC4_TYPELESS",L"1 成分、型なしブロック圧縮フォーマット")
166+ (L"DXGI_FORMAT_BC4_UNORM",L"1 成分、ブロック圧縮フォーマット")
167+ (L"DXGI_FORMAT_BC4_SNORM",L"1 成分、ブロック圧縮フォーマット")
168+ (L"DXGI_FORMAT_BC5_TYPELESS",L"2 成分、型なしブロック圧縮フォーマット")
169+ (L"DXGI_FORMAT_BC5_UNORM",L"2 成分、ブロック圧縮フォーマット")
170+ (L"DXGI_FORMAT_BC5_SNORM",L"2 成分、ブロック圧縮フォーマット")
171+ (L"DXGI_FORMAT_B5G6R5_UNORM",L"3 成分、16 ビット符号なし正規化整数フォーマット")
172+ (L"DXGI_FORMAT_B5G5R5A1_UNORM",L"1 ビット アルファをサポートする 4 成分、16 ビット符号なし正規化整数フォーマット")
173+ (L"DXGI_FORMAT_B8G8R8A8_UNORM",L"8 ビット アルファをサポートする 4 成分、16 ビット符号なし正規化整数フォーマット")
174+ (L"DXGI_FORMAT_B8G8R8X8_UNORM",L"4 成分、16 ビット符号なし正規化整数フォーマット")
175+ (L"DXGI_FORMAT_FORCE_UINT",L"コンパイル時に、この列挙型のサイズを 32 ビットにするために定義されています。この値を指定しない場合、一部のコンパイラでは列挙型を 32 ビット以外のサイズでコンパイル可能この定数が使用されることはありません。");
176+
177+ // スキャンライン情報
178+
179+ std::vector<mode_info> scanline_orders =
180+ boost::assign::list_of<mode_info>
181+ (L"DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED",L"走査線の順序が指定されていません。")
182+ (L"DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE",L"イメージは先頭の走査線~最後の走査線から作成され、スキップされる走査線はありません。")
183+ (L"DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST",L"イメージが上部のフィールドから作成されます。")
184+ (L"DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST",L"イメージが下部のフィールドから作成されます。");
185+
186+ // スケーリングパラメータ
187+ std::vector<mode_info> scalings = boost::assign::list_of<mode_info>
188+ (L"DXGI_MODE_SCALING_UNSPECIFIED",L"スケーリングが指定されていません。")
189+ (L"DXGI_MODE_SCALING_CENTERED",L"スケーリングなしを指定します。イメージはディスプレイの中央に配置されます。通常、このフラグは固定ドットピッチ ディスプレイ (LED ディスプレイなど) に使用します。")
190+ (L"DXGI_MODE_SCALING_STRETCHED",L"拡大スケーリングを指定します。");
191+
192+ struct simple_vertex
193+ {
194+ XMFLOAT3 pos;
195+ XMFLOAT3 norm;
196+ XMFLOAT2 tex;
197+ };
198+
199+ struct cb_never_changes
200+ {
201+ XMMATRIX mView;
202+ XMFLOAT4 vLightDir;
203+ };
204+
205+ struct cb_change_on_resize
206+ {
207+ XMMATRIX mProjection;
208+ };
209+
210+ struct cb_changes_every_frame
211+ {
212+ XMMATRIX mWorld;
213+ XMFLOAT4 vLightColor;
214+
215+ // XMFLOAT4 vMeshColor;
216+ };
30217 template <typename ProcType>
31- LRESULT base_win32_window<ProcType>::window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
218+ typename base_win32_window<ProcType>::result_t base_win32_window<ProcType>::window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
32219 {
33220
34221 switch (message)
@@ -54,23 +241,23 @@ namespace sf
54241 case WM_LBUTTONDOWN:
55242 return on_left_mouse_button_down(
56243 wParam,dpi_.scale_x(
57- GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
58- ;
244+ GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
245+ ;
59246 ;
60247 case WM_LBUTTONUP:
61248 return on_left_mouse_button_up(
62249 wParam,dpi_.scale_x(
63- GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
64- ;
250+ GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
251+ ;
65252 case WM_LBUTTONDBLCLK:
66253 return on_left_mouse_button_double_click(wParam,
67254 dpi_.scale_x(
68- GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
69- ;
255+ GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
256+ ;
70257 case WM_MOUSEMOVE:
71258 {
72- return on_mouse_move(wParam,
73- dpi_.scale_x(
259+ return on_mouse_move(wParam,
260+ dpi_.scale_x(
74261 GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
75262 ;
76263 // on_mouse_move(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam),wParam);
@@ -78,8 +265,8 @@ namespace sf
78265 case WM_MOUSEWHEEL:
79266 return on_mouse_wheel(GET_KEYSTATE_WPARAM(wParam),GET_WHEEL_DELTA_WPARAM(wParam),
80267 dpi_.scale_x(
81- GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
82- ;
268+ GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam)))
269+ ;
83270 case WM_MOUSELEAVE:
84271 return on_mouse_leave() ;
85272 case WM_KEYDOWN:
@@ -98,14 +285,18 @@ namespace sf
98285 return on_timer(wParam);
99286 case WM_NOTIFY:
100287 return on_notify(reinterpret_cast<NMHDR*>(lParam));
288+ case WM_DWMCOMPOSITIONCHANGED:
289+ return on_dwm_composition_changed();
290+ //case WM_DWMCOLORIZATIONCOLORCHANGED:
291+ // return on_dwm_colorlizationcolor_changed
101292 }
102293
103294 // 他のWindowメッセージを派生クラス側でフックできるようにする
104295 return other_window_proc(hwnd,message,wParam,lParam);
105296
106297 };
107-
108- template <typename ProcType>
298+
299+ template <typename ProcType>
109300 void base_win32_window<ProcType>::register_class (
110301 const wchar_t * menu_name,
111302 uint32_t style ,
@@ -117,18 +308,19 @@ namespace sf
117308 HICON hIconSm
118309 )
119310 {
120- wnd_class_.reset(new sf::window_class_ex(menu_name,name_,HINST_THISCOMPONENT,thunk_proc_,style,cbClsExtra,cbWndExtra,hIcon,hCursor,hbrBackground,hIconSm));
311+ wnd_class_.reset(new sf::window_class_ex(menu_name,name_,HINST_THISCOMPONENT,&start_wnd_proc,style,cbClsExtra,cbWndExtra,hIcon,hCursor,hbrBackground,hIconSm));
121312 }
122313
123314 /** デフォルト設定 */
124315 template <typename ProcType>
125316 void base_win32_window<ProcType>::register_class()
126317 {
127- wnd_class_.reset(new sf::window_class_ex(0,name_,HINST_THISCOMPONENT,thunk_proc_));
318+ //register_class(0,0);
319+ wnd_class_.reset(new sf::window_class_ex(0,name_,HINST_THISCOMPONENT,&start_wnd_proc));
128320 }
129321
130322 template <typename ProcType>
131- void base_win32_window<ProcType>::create_window()
323+ void base_win32_window<ProcType>::create_window(HWND parent)
132324 {
133325 // Create the application window.
134326 //
@@ -139,15 +331,17 @@ namespace sf
139331
140332
141333 // Windowを作成する
142- CreateWindow(
334+ // Windowを作成する
335+ CreateWindowEx(
336+ WS_EX_APPWINDOW/* | WS_EX_LAYERED */,
143337 name_.c_str(),
144338 title_.c_str(),
145- WS_OVERLAPPEDWINDOW,
339+ WS_OVERLAPPEDWINDOW /*| WS_POPUP*/,
146340 CW_USEDEFAULT,
147341 CW_USEDEFAULT,
148- static_cast<uint32_t>(dpi_.scale_x(width_)),
149- static_cast<uint32_t>(dpi_.scale_y(height_)),
150- NULL,
342+ static_cast<uint32_t>(width_),
343+ static_cast<uint32_t>(height_),
344+ parent,
151345 NULL,
152346 HINST_THISCOMPONENT,
153347 this
@@ -155,7 +349,7 @@ namespace sf
155349 ::GetWindowPlacement(hwnd_,&wp_);
156350 }
157351
158-
352+
159353 //void base_win32_window::show()
160354 //{
161355 // //HRESULT hr = S_OK;
@@ -183,21 +377,800 @@ namespace sf
183377 template <typename ProcType>
184378 base_win32_window<ProcType>::~base_win32_window()
185379 {
186-
187380 }
188381
189382 template <typename ProcType>
190383 base_win32_window<ProcType>::base_win32_window(const std::wstring& title,const std::wstring& name,bool fit_to_display,float width,float height)
191- : title_(title),name_(name),fit_to_display_(fit_to_display),width_(width),height_(height),thunk_(this,base_win32_window::WndProc),hwnd_(0)
384+ : title_(title),name_(name),fit_to_display_(fit_to_display),width_(width),height_(height),thunk_(this,reinterpret_cast<ProcType::proc_type>(base_win32_window::WndProc)),hwnd_(0),timer_(*this,10)
192385 {
386+ ZeroMemory(&actual_desc_,sizeof(DXGI_MODE_DESC));
387+ width_ = dpi_.scale_x(width_);
388+ height_ = dpi_.scale_y(height_);
193389 memset(&wp_,0,sizeof(wp_));
194390 wp_.length = sizeof(WINDOWPLACEMENT);
195391 thunk_proc_ = (WNDPROC)thunk_.getCode();
196- //create_device_independent_resources();
392+ create_device_independent_resources();
393+ }
394+
395+ template <typename ProcType>
396+ typename base_win32_window<ProcType>::result_t base_win32_window<ProcType>::on_nccreate(CREATESTRUCT *p)
397+ {
398+
399+ return std::is_same<proc_t,wndproc>::value?1:FALSE;
400+ }
401+
402+ template <typename ProcType>
403+ void base_win32_window<ProcType>::create_device_independent_resources()
404+ {
405+
406+ // DXGI Factory の 生成
407+
408+ if(!dxgi_factory_)
409+ {
410+ THROW_IFERR(CreateDXGIFactory1(__uuidof(IDXGIFactory1),reinterpret_cast<void**>(dxgi_factory_.GetAddressOf())));
411+ get_dxgi_information();
412+ }
413+
414+ }
415+
416+ template <typename ProcType>
417+ void base_win32_window<ProcType>::create_device(){
418+ calc_client_size();
419+ HRESULT hr = S_OK;
420+ init_ = false;
421+ RECT rc;
422+ GetWindowRect(hwnd_,&rc);
423+
424+ // アダプタデバイス情報の取得
425+ //LARGE_INTEGER version;
426+ THROW_IFERR(dxgi_factory_->EnumAdapters1(0,&adapter_));
427+ //THROW_IFERR(adapter_->CheckInterfaceSupport( __uuidof(ID3D10Device),&version));
428+
429+
430+ // D3DDeviceの作成
431+
432+ std::vector<D3D_FEATURE_LEVEL> feature_levels =
433+ boost::assign::list_of<D3D_FEATURE_LEVEL>
434+ (D3D_FEATURE_LEVEL_11_0 ) // DirectX11対応GPU
435+ (D3D_FEATURE_LEVEL_10_1) // DirectX10.1対応GPU
436+ (D3D_FEATURE_LEVEL_10_0 ); // DirectX10対応GPU
437+
438+ D3D_FEATURE_LEVEL level;
439+ THROW_IFERR(::D3D11CreateDevice(
440+ adapter_.Get(),
441+ D3D_DRIVER_TYPE_UNKNOWN ,
442+ NULL,
443+ D3D11_CREATE_DEVICE_DEBUG,
444+ &feature_levels[0],
445+ feature_levels.size(),
446+ D3D11_SDK_VERSION,
447+ &d3d_device_,
448+ &level,
449+ &d3d_context_));
450+
451+ THROW_IFERR(adapter_->EnumOutputs(0,&output_));
452+
453+ // MSAA
454+ DXGI_SAMPLE_DESC msaa;
455+ for(int i = 0; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++){
456+ UINT q;
457+ if SUCCEEDED(d3d_device_->CheckMultisampleQualityLevels(DXGI_FORMAT_D24_UNORM_S8_UINT, i, &q)){
458+ if(1 < q){
459+ msaa.Count = i;
460+ msaa.Quality = q - 1;
461+ break;
462+ }
463+ }
464+ }
465+
466+ // 表示モード
467+ DXGI_MODE_DESC desired_desc = {};// , actual_desc_ = {};
468+ // 各色8ビットで符号化なし正規化数
469+ desired_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
470+ desired_desc.Height = height_;// 高さ
471+ desired_desc.Width = width_;// 幅
472+ desired_desc.Scaling = DXGI_MODE_SCALING_CENTERED;// スケーリングなし
473+ // リフレッシュレートを60Hzを要求する
474+
475+ desired_desc.RefreshRate.Numerator = 60000;
476+ desired_desc.RefreshRate.Denominator = 1000;
477+ // 近いモードを検索
478+ THROW_IF_ERR(output_->FindClosestMatchingMode(&desired_desc,&actual_desc_,d3d_device_.Get()));
479+
480+ //// スワップチェーンの作成
481+ //{
482+ // DXGI_SWAP_CHAIN_DESC desc = {};
483+
484+ // desc.BufferDesc = actual_desc_;
485+ // desc.SampleDesc.Count = 1;
486+ // desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
487+ // desc.BufferCount = 1;
488+ // // desc.SampleDesc = msaa;
489+ // desc.OutputWindow = hwnd_;
490+ // //desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
491+ // desc.Windowed = TRUE;
492+ // desc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
493+
494+ // THROW_IFERR(dxgi_factory_->CreateSwapChain(d3d_device_,&desc,&swap_chain_));
495+
496+ //}
497+
498+ // バックバッファの作成
499+
500+ D3D11_TEXTURE2D_DESC desc = {0};
501+ desc.Width = actual_desc_.Width;
502+ desc.Height = actual_desc_.Height;
503+ desc.Format = actual_desc_.Format;
504+ desc.MipLevels = 1;
505+ desc.SampleDesc.Count = 1;
506+ desc.SampleDesc.Quality = 0;
507+ desc.ArraySize = 1;
508+ desc.Usage = D3D11_USAGE_DEFAULT;
509+ desc.BindFlags = D3D11_BIND_RENDER_TARGET;
510+ desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
511+ THROW_IF_ERR(d3d_device_->CreateTexture2D(&desc,NULL,&back_buffer_));
512+
513+ // スワップチェーン依存リソースの作成
514+
515+ create_swapchain_dependent_resources();
516+
517+ {
518+ // バーテックスシェーダのコンパイル
519+ ID3DBlobPtr vsblob,vserrblob;
520+ DWORD compile_flag = D3DCOMPILE_ENABLE_STRICTNESS;
521+#if defined( DEBUG ) || defined( _DEBUG )
522+ compile_flag |= D3DCOMPILE_DEBUG;
523+#endif
524+
525+ HRESULT hr = D3DCompileFromFile
526+ (
527+ L"dxgi_test.fx", NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE , "VS", "vs_5_0",
528+ compile_flag, 0, &vsblob, &vserrblob );
529+ if( FAILED( hr ) )
530+ {
531+ if( vserrblob != NULL )
532+ OutputDebugStringA( (char*)vserrblob->GetBufferPointer() );
533+ if( vserrblob ) vserrblob.Reset();
534+ throw sf::win32_error_exception(hr);
535+ }
536+
537+ // バーテックスシェーダの生成
538+ THROW_IFERR(d3d_device_->CreateVertexShader( vsblob->GetBufferPointer(), vsblob->GetBufferSize(), NULL, &v_shader_ ));
539+
540+ // 入力頂点レイアウトの定義
541+ D3D11_INPUT_ELEMENT_DESC
542+ layout[] = {
543+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
544+ { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
545+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }};
546+ ;
547+
548+ // 入力頂点レイアウトの生成
549+ THROW_IFERR(d3d_device_->CreateInputLayout( layout, ARRAYSIZE(layout), vsblob->GetBufferPointer(),
550+ vsblob->GetBufferSize(), &input_layout_ ));
551+ vsblob.Reset();
552+ }
553+
554+ // 入力レイアウトの設定
555+ d3d_context_->IASetInputLayout( input_layout_.Get() );
556+
557+ // ピクセル・シェーダーのコンパイル
558+ {
559+ ID3DBlobPtr psblob,pserror;
560+ DWORD compile_flag = D3DCOMPILE_ENABLE_STRICTNESS;
561+#if defined( DEBUG ) || defined( _DEBUG )
562+ compile_flag |= D3DCOMPILE_DEBUG;
563+#endif
564+ HRESULT hr = D3DCompileFromFile( L"dxgi_test.fx", NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, "PS", "ps_5_0",
565+ compile_flag, 0, &psblob, &pserror);
566+ if( FAILED( hr ) )
567+ {
568+ if( pserror != NULL )
569+ OutputDebugStringA( (char*)pserror->GetBufferPointer() );
570+ safe_release(pserror);
571+ throw sf::win32_error_exception(hr);
572+ }
573+
574+ // ピクセルシェーダの作成
575+ THROW_IFERR(d3d_device_->CreatePixelShader( psblob->GetBufferPointer(), psblob->GetBufferSize(), NULL, &p_shader_ ));
576+
577+ psblob.Reset();
578+ }
579+
580+ // バーテックスバッファの作成
581+ // Create vertex buffer
582+ simple_vertex vertices[] =
583+ {
584+ { XMFLOAT3( 0.0f, 0.0f,0.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ) , XMFLOAT2( 0.0f, 0.0f ) },
585+ { XMFLOAT3( 640.0f, 0.0f, 0.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
586+ { XMFLOAT3( 0.0f, 480.0f, 0.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ) , XMFLOAT2( 0.0f, 1.0f ) },
587+ { XMFLOAT3( 640.0f, 480.0f, 0.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) }
588+
589+ //{ XMFLOAT3( -1.0f, -1.0f, 2.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ) , XMFLOAT2( 1.0f, 1.0f ) },
590+ //{ XMFLOAT3( 1.0f, -1.0f, 2.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
591+ //{ XMFLOAT3( -1.0f, 1.0f, 2.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ) , XMFLOAT2( 1.0f, 0.0f ) },
592+ //{ XMFLOAT3( 1.0f, 1.0f, 2.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }
593+ // ---------------------
594+ //{ XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT3( 0.0f, 1.0f, 0.0f ),XMFLOAT2( 0.0f, 0.0f ) },
595+ //{ XMFLOAT3( 1.0f, 1.0f, -1.0f ),XMFLOAT3( 0.0f, 1.0f, 0.0f ), XMFLOAT2( 1.0f, 0.0f ) },
596+ //{ XMFLOAT3( 1.0f, 1.0f, 1.0f ),XMFLOAT3( 0.0f, 1.0f, 0.0f ), XMFLOAT2( 1.0f, 1.0f ) },
597+ //{ XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT3( 0.0f, 1.0f, 0.0f ) ,XMFLOAT2( 0.0f, 1.0f ) },
598+
599+ //{ XMFLOAT3( -1.0f, -1.0f, -1.0f ),XMFLOAT3( 0.0f, -1.0f, 0.0f ), XMFLOAT2( 0.0f, 0.0f ) },
600+ //{ XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT3( 0.0f, -1.0f, 0.0f ) ,XMFLOAT2( 1.0f, 0.0f ) },
601+ //{ XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT3( 0.0f, -1.0f, 0.0f ) , XMFLOAT2( 1.0f, 1.0f ) },
602+ //{ XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT3( 0.0f, -1.0f, 0.0f ),XMFLOAT2( 0.0f, 1.0f ) },
603+
604+ //{ XMFLOAT3( -1.0f, -1.0f, 1.0f ),XMFLOAT3( -1.0f, 0.0f, 0.0f ) , XMFLOAT2( 0.0f, 0.0f ) },
605+ //{ XMFLOAT3( -1.0f, -1.0f, -1.0f ),XMFLOAT3( -1.0f, 0.0f, 0.0f ), XMFLOAT2( 1.0f, 0.0f ) },
606+ //{ XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT3( -1.0f, 0.0f, 0.0f ),XMFLOAT2( 1.0f, 1.0f ) },
607+ //{ XMFLOAT3( -1.0f, 1.0f, 1.0f ),XMFLOAT3( -1.0f, 0.0f, 0.0f ), XMFLOAT2( 0.0f, 1.0f ) },
608+
609+ //{ XMFLOAT3( 1.0f, -1.0f, 1.0f ),XMFLOAT3( 1.0f, 0.0f, 0.0f ), XMFLOAT2( 0.0f, 0.0f ) },
610+ //{ XMFLOAT3( 1.0f, -1.0f, -1.0f ),XMFLOAT3( 1.0f, 0.0f, 0.0f ), XMFLOAT2( 1.0f, 0.0f ) },
611+ //{ XMFLOAT3( 1.0f, 1.0f, -1.0f ),XMFLOAT3( 1.0f, 0.0f, 0.0f ), XMFLOAT2( 1.0f, 1.0f ) },
612+ //{ XMFLOAT3( 1.0f, 1.0f, 1.0f ),XMFLOAT3( 1.0f, 0.0f, 0.0f ), XMFLOAT2( 0.0f, 1.0f ) },
613+
614+ //{ XMFLOAT3( -1.0f, -1.0f, -1.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ) , XMFLOAT2( 0.0f, 0.0f ) },
615+ //{ XMFLOAT3( 1.0f, -1.0f, -1.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
616+ //{ XMFLOAT3( 1.0f, 1.0f, -1.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
617+ //{ XMFLOAT3( -1.0f, 1.0f, -1.0f ),XMFLOAT3( 0.0f, 0.0f, -1.0f ) , XMFLOAT2( 0.0f, 1.0f ) },
618+
619+ //{ XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 1.0f ) , XMFLOAT2( 0.0f, 0.0f ) },
620+ //{ XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 1.0f ) , XMFLOAT2( 1.0f, 0.0f ) },
621+ //{ XMFLOAT3( 1.0f, 1.0f, 1.0f ),XMFLOAT3( 0.0f, 0.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
622+ //{ XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 1.0f ),XMFLOAT2( 0.0f, 1.0f ) }
623+ };
624+ //std::vector<simple_vertex> vertices = boost::assign::list_of<simple_vertex>
625+ //
626+ // ( XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) )
627+ // ( XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) )
628+ // ( XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) )
629+ // ( XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) )
630+
631+ // ( XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) )
632+ // ( XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) )
633+ // ( XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) )
634+ // ( XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) )
635+
636+ // ( XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) )
637+ // ( XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) )
638+ // ( XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) )
639+ // ( XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) )
640+
641+ // ( XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) )
642+ // ( XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) )
643+ // ( XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) )
644+ // ( XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) )
645+
646+ // ( XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) )
647+ // ( XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) )
648+ // ( XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) )
649+ // ( XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) )
650+
651+ // ( XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) )
652+ // ( XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) )
653+ // ( XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) )
654+ // ( XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) );
655+
656+ D3D11_BUFFER_DESC bd = {};
657+ bd.Usage = D3D11_USAGE_DEFAULT;
658+ bd.ByteWidth = sizeof( simple_vertex ) * 4;
659+ bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
660+ bd.CPUAccessFlags = 0;
661+
662+ D3D11_SUBRESOURCE_DATA init_data = {};
663+ init_data.pSysMem = vertices;
664+ THROW_IFERR(d3d_device_->CreateBuffer( &bd, &init_data, &v_buffer_ ));
665+
666+ // 頂点バッファのセット
667+ uint32_t stride = sizeof( simple_vertex );
668+ uint32_t offset = 0;
669+ d3d_context_->IASetVertexBuffers( 0, 1, v_buffer_.GetAddressOf(), &stride, &offset );
670+
671+ // インデックスバッファの生成
672+ WORD indices[] =
673+ {
674+ 0,1,2,
675+ 2,3,1
676+ //3,1,0,
677+ //2,1,3,
678+ //6,4,5,
679+ //7,4,6,
680+ //11,9,8,
681+ //10,9,11,
682+ //14,12,13,
683+ //15,12,14,
684+ //19,17,16,
685+ //18,17,19,
686+ //22,20,21,
687+ //23,20,22
688+ };
689+
690+ bd.Usage = D3D11_USAGE_DEFAULT;
691+ bd.ByteWidth = sizeof( WORD ) * 6;
692+ bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
693+ bd.CPUAccessFlags = 0;
694+ init_data.pSysMem = indices;
695+ THROW_IFERR(d3d_device_->CreateBuffer( &bd, &init_data, &i_buffer_ ));
696+
697+ // インデックスバッファのセット
698+ d3d_context_->IASetIndexBuffer( i_buffer_.Get(), DXGI_FORMAT_R16_UINT, 0 );
699+
700+ // プリミティブの形態を指定する
701+ d3d_context_->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
702+
703+ // 定数バッファを生成する。
704+ bd.Usage = D3D11_USAGE_DEFAULT;
705+ bd.ByteWidth = sizeof(cb_never_changes);
706+ bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
707+ bd.CPUAccessFlags = 0;
708+ THROW_IFERR(d3d_device_->CreateBuffer( &bd, NULL, &cb_never_changes_ ));
709+
710+ bd.ByteWidth = sizeof(cb_change_on_resize);
711+ THROW_IFERR(d3d_device_->CreateBuffer( &bd, NULL, &cb_change_on_resize_ ));
712+
713+ bd.ByteWidth = sizeof(cb_changes_every_frame);
714+ THROW_IFERR(d3d_device_->CreateBuffer( &bd, NULL, &cb_changes_every_frame_ ));
715+
716+ // テクスチャのロード
717+ ID3D11ResourcePtr ptr;
718+ THROW_IFERR(CreateDDSTextureFromFile( d3d_device_.Get(), L"SF.dds", &ptr, &shader_res_view_, NULL ));
719+// THROW_IFERR(CreateDDSTextureFromFile( d3d_device_, L"SF.dds", NULL, NULL, &shader_res_view_, NULL ));
720+
721+ // サンプルステートの生成
722+ D3D11_SAMPLER_DESC sdesc = {};
723+ sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
724+ sdesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
725+ sdesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
726+ sdesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
727+ sdesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
728+ sdesc.MinLOD = 0;
729+ sdesc.MaxLOD = D3D11_FLOAT32_MAX;
730+ THROW_IFERR(d3d_device_->CreateSamplerState( &sdesc, &sampler_state_ ));
731+
732+ // ワールド座標変換行列のセットアップ
733+ mat_world_ = XMMatrixIdentity();
734+
735+ //g_vMeshColor( 0.7f, 0.7f, 0.7f, 1.0f );
736+ //
737+ init_view_matrix();
738+
739+
740+
741+ // 動的テクスチャの生成
742+ {
743+ //D3D11_TEXTURE2D_DESC desc = {0};
744+ //desc.Width = 256;
745+ //desc.Height = 256;
746+ //desc.Format = actual_desc_.Format;
747+ //desc.MipLevels = 1;
748+ //desc.SampleDesc.Count = 1;
749+ //desc.SampleDesc.Quality = 0;
750+ //desc.ArraySize = 1;
751+ //desc.Usage = D3D11_USAGE_DEFAULT;
752+ //desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
753+ //// desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
754+ //THROW_IF_ERR(d3d_device_->CreateTexture2D(&desc,NULL,&cube_texture_));
755+ //THROW_IF_ERR(d3d_device_->CreateRenderTargetView(cube_texture_,0,&cube_view_));
756+
757+ //// 深度バッファの作成
758+ //D3D11_TEXTURE2D_DESC depth = {} ;
759+ //depth.Width = desc.Width;//rc.right - rc.left;client_width_;
760+ //depth.Height = desc.Height;//rc.bottom - rc.top;client_height_;
761+ //depth.MipLevels = 1;
762+ //depth.ArraySize = 1;
763+ //depth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
764+ //depth.SampleDesc.Count = 1;
765+ //depth.SampleDesc.Quality = 0;
766+ //depth.Usage = D3D11_USAGE_DEFAULT;
767+ //depth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
768+ //depth.CPUAccessFlags = 0;
769+ //depth.MiscFlags = 0;
770+ //THROW_IF_ERR(d3d_device_->CreateTexture2D( &depth, NULL, &cube_depth_texture_ ));
771+
772+ //D3D11_DEPTH_STENCIL_VIEW_DESC dsv = {};
773+ //dsv.Format = depth.Format;
774+ //dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
775+ //dsv.Texture2D.MipSlice = 0;
776+ //THROW_IF_ERR(d3d_device_->CreateDepthStencilView( cube_depth_texture_, &dsv, &cube_depth_view_ ));
777+ //THROW_IF_ERR(d3d_device_->CreateShaderResourceView(cube_texture_,0,&cube_shader_res_view_));
778+
779+ //D3D11_SAMPLER_DESC sdesc = {};
780+ //sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
781+ //sdesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
782+ //sdesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
783+ //sdesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
784+ //sdesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
785+ //sdesc.MinLOD = 0;
786+ //sdesc.MaxLOD = D3D11_FLOAT32_MAX;
787+ //THROW_IFERR(d3d_device_->CreateSamplerState( &sdesc, &cube_sampler_state_ ));
788+ //cube_mat_projection_ = XMMatrixPerspectiveFovLH( XM_PIDIV4, /*(rc.right - rc.left)/(rc.bottom - rc.top)*/256 / 256, 0.01f, 100.0f );
789+
790+ }
791+ //
792+
793+ init_ = true;// 初期化完了
794+ }
795+
796+
797+ template <typename ProcType>
798+ void base_win32_window<ProcType>::init_view_matrix()
799+ {
800+ // ビュー行列のセットアップ
801+ //基本値設定
802+ float aspect = (float) width_ / height_; //アスペクト比(高さを1としたときの幅)
803+ float depth = 1.0f; //奥行きZ
804+ float fovy = (float)atan(1.0f / depth) * 2.0f; //視野をZ=0でデバイスの幅と高さに合わせる
805+
806+ XMVECTOR eye = { 0.0f, 0.0f, -depth, 0.0f };
807+ XMVECTOR at = { 0.0f, 0.0f, 0.0f, 0.0f};
808+ XMVECTOR up = { 0.0f, 1.0f, 0.0f, 0.0f };
809+ mat_view_ = XMMatrixLookAtLH( eye, at, up );
810+ cb_never_changes cnc;
811+ cnc.mView = XMMatrixTranspose( mat_view_ );
812+ //cnc.vLightColor = XMFLOAT4( 1.0f, 0.5f, 0.5f, 1.0f );
813+ cnc.vLightDir = XMFLOAT4(0.577f, 0.577f, -0.977f, 1.0f);
814+ // 定数バッファに格納
815+ d3d_context_->UpdateSubresource( cb_never_changes_.Get(), 0, NULL, &cnc, 0, 0 );
816+
817+ // 投影行列のセットアップ
818+
819+ //mat_projection_ = XMMatrixPerspectiveFovLH( XM_PIDIV4, /*(rc.right - rc.left)/(rc.bottom - rc.top)*/width_ / height_, 0.01f, 100.0f );
820+ //mat_projection_ = XMMatrixPerspectiveFovLH( fovy, aspect, 0.01f, 100.0f );
821+ mat_projection_ = XMMatrixPerspectiveFovLH( fovy, 1.0, 0.0001f, 100.0f );
822+ cb_change_on_resize ccor;
823+ ccor.mProjection = XMMatrixTranspose( mat_projection_ );
824+ // 定数バッファに格納
825+ d3d_context_->UpdateSubresource( cb_change_on_resize_.Get(), 0, NULL, &ccor, 0, 0 );
826+
827+ }
828+ template <typename ProcType>
829+ void base_win32_window<ProcType>::create_swapchain_dependent_resources()
830+ {
831+
832+ // ビューの作成
833+ //THROW_IF_ERR(swap_chain_->GetBuffer(0,texture_.GetIID(),(void**)&texture_));
834+ //D3D11_TEXTURE2D_DESC desc;
835+ //texture_->GetDesc(&desc);
836+
837+ //THROW_IF_ERR(d3d_device_->CreateRenderTargetView(texture_,0,&view_));
838+ //texture_.Release();
839+ THROW_IF_ERR(d3d_device_->CreateRenderTargetView(back_buffer_.Get(),0,view_.GetAddressOf()));
840+ D3D11_TEXTURE2D_DESC desc;
841+ back_buffer_->GetDesc(&desc);
842+
843+ // 深度バッファの作成
844+ D3D11_TEXTURE2D_DESC depth = {} ;
845+ depth.Width = desc.Width;//rc.right - rc.left;client_width_;
846+ depth.Height = desc.Height;//rc.bottom - rc.top;client_height_;
847+ depth.MipLevels = 1;
848+ depth.ArraySize = 1;
849+ depth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
850+ depth.SampleDesc.Count = 1;
851+ depth.SampleDesc.Quality = 0;
852+ depth.Usage = D3D11_USAGE_DEFAULT;
853+ depth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
854+ depth.CPUAccessFlags = 0;
855+ depth.MiscFlags = 0;
856+ THROW_IF_ERR(d3d_device_->CreateTexture2D( &depth, NULL, &depth_texture_ ));
857+
858+ D3D11_DEPTH_STENCIL_VIEW_DESC dsv = {};
859+ dsv.Format = depth.Format;
860+ dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
861+ dsv.Texture2D.MipSlice = 0;
862+ THROW_IF_ERR(d3d_device_->CreateDepthStencilView( depth_texture_.Get(), &dsv, depth_view_.GetAddressOf() ));
863+
864+ // OMステージに登録する
865+ // d3d_context_->OMSetRenderTargets( 1, &view_.Get(), depth_view_ );
866+ d3d_context_->OMSetRenderTargets( 1, view_.GetAddressOf(), depth_view_.Get() );
867+
868+ // ビューポートの設定
869+ D3D11_VIEWPORT vp;
870+ vp.Width = depth.Width;//client_width_;
871+ vp.Height = depth.Height;//client_height_;
872+ vp.MinDepth = 0.0f;
873+ vp.MaxDepth = 1.0f;
874+ vp.TopLeftX = 0;
875+ vp.TopLeftY = 0;
876+ d3d_context_->RSSetViewports( 1, &vp );
877+
878+ ID3D11RasterizerState* hpRasterizerState = NULL;
879+ D3D11_RASTERIZER_DESC hRasterizerDesc = {
880+ D3D11_FILL_SOLID,
881+ D3D11_CULL_NONE, //ポリゴンの裏表を無くす
882+ FALSE,
883+ 0,
884+ 0.0f,
885+ FALSE,
886+ FALSE,
887+ FALSE,
888+ FALSE,
889+ FALSE
890+ };
891+ d3d_device_->CreateRasterizerState(&hRasterizerDesc,&hpRasterizerState);
892+ d3d_context_->RSSetState(hpRasterizerState);
893+ }
894+
895+ template <typename ProcType>
896+ void base_win32_window<ProcType>::discard_swapchain_dependent_resources()
897+ {
898+ safe_release(depth_view_);
899+ safe_release(depth_texture_);
900+ safe_release(view_);
901+ safe_release(texture_);
902+ }
903+
904+ template <typename ProcType>
905+ void base_win32_window<ProcType>::discard_device()
906+ {
907+ safe_release(sampler_state_);
908+ safe_release(shader_res_view_);
909+ safe_release(cb_changes_every_frame_);
910+ safe_release(cb_change_on_resize_);
911+ safe_release(cb_never_changes_);
912+ safe_release(i_buffer_);
913+ safe_release(v_buffer_);
914+ safe_release(p_shader_);
915+ safe_release(input_layout_);
916+ safe_release(v_shader_);
917+ discard_swapchain_dependent_resources();
918+ safe_release(back_buffer_);
919+ //safe_release(cube_sampler_state_);
920+ //safe_release(cube_shader_res_view_);
921+ //safe_release(cube_view_);
922+ //safe_release(cube_depth_view_);
923+ //safe_release(cube_texture_);
924+ //safe_release(cube_depth_texture_);
925+ //safe_release(render_target_);
926+// safe_release(swap_chain_);
927+ safe_release(d3d_context_);
928+ safe_release(d3d_device_);
929+ safe_release(adapter_);
930+
931+ }
932+
933+ template <typename ProcType>
934+ void base_win32_window<ProcType>::discard_device_independant_resources(){
935+ safe_release(dxgi_factory_);
936+ }
937+
938+ template <typename ProcType>
939+ void base_win32_window<ProcType>::get_dxgi_information()
940+ {
941+ int i = 0;
942+
943+ while(1){
944+ IDXGIAdapter1Ptr adapter;
945+ HRESULT hr = dxgi_factory_->EnumAdapters1(i,&adapter);
946+ if(hr == DXGI_ERROR_NOT_FOUND)
947+ {
948+ break;
949+ }
950+ DXGI_ADAPTER_DESC1 desc;
951+ adapter->GetDesc1(&desc);
952+ //adapter->CheckInterfaceSupport();
953+
954+ wdout << desc.Description << std::endl;
955+ wdout << desc.DedicatedVideoMemory << std::endl;
956+ IDXGIDevice1Ptr device;
957+
958+ uint32_t oi = 0;
959+
960+
961+ while(1)
962+ {
963+ IDXGIOutputPtr output;
964+ if(adapter->EnumOutputs(oi,&output) == DXGI_ERROR_NOT_FOUND){
965+ break;
966+ }
967+ DXGI_OUTPUT_DESC output_desc;
968+ output->GetDesc(&output_desc);
969+ UINT num = 0;
970+ DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
971+ UINT flags = DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING;
972+
973+ output->GetDisplayModeList(format,flags,&num,0);
974+ boost::shared_array<DXGI_MODE_DESC> disp_modes(new DXGI_MODE_DESC[num]);
975+ output->GetDisplayModeList(format,flags,&num,&disp_modes[0]);
976+ //output->GetFrameStatistics
977+ for(uint32_t mode_index = 0;mode_index < num;++mode_index)
978+ {
979+ DXGI_MODE_DESC& mode(disp_modes[mode_index]);
980+ wdout << boost::wformat(L"Format: %s %s \n Width: %d Height: %d RefleshRate: %d/%d Scaling:%s %s \n Scanline: %s %s ")
981+ % display_modes[mode.Format].name % display_modes[mode.Format].description
982+ % mode.Width % mode.Height
983+ % mode.RefreshRate.Numerator % mode.RefreshRate.Denominator
984+ % scalings[mode.Scaling].name % scalings[mode.Scaling].description
985+ % scanline_orders[mode.ScanlineOrdering].name
986+ % scanline_orders[mode.ScanlineOrdering].description
987+ << std::endl;
988+ }
989+ // output->
990+ wdout << output_desc.DeviceName << std::endl;
991+ oi++;
992+ }
993+
994+ adapter.Reset();
995+ ++i;
996+ }
997+ }
998+
999+ template <typename ProcType>
1000+ typename base_win32_window<ProcType>::result_t base_win32_window<ProcType>::on_size(uint32_t flag,uint32_t width,uint32_t height)
1001+ {
1002+ if(init_ && !(width == 0 || height == 0))
1003+ {
1004+ update_window_size();
1005+ calc_client_size();
1006+ discard_swapchain_dependent_resources();
1007+ back_buffer_.Reset();
1008+ D3D11_TEXTURE2D_DESC desc = {0};
1009+ desc.Width = width_;
1010+ desc.Height = height_;
1011+ desc.Format = actual_desc_.Format;
1012+ desc.MipLevels = 1;
1013+ desc.SampleDesc.Count = 1;
1014+ desc.SampleDesc.Quality = 0;
1015+ desc.ArraySize = 1;
1016+ desc.Usage = D3D11_USAGE_DEFAULT;
1017+ desc.BindFlags = D3D11_BIND_RENDER_TARGET;
1018+ desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
1019+ THROW_IF_ERR(d3d_device_->CreateTexture2D(&desc,NULL,&back_buffer_));
1020+ //swap_chain_->ResizeBuffers(0,0,0,DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
1021+ create_swapchain_dependent_resources();
1022+ init_view_matrix();
1023+
1024+ // リージョンの設定
1025+ //HRGN rgn = CreateRectRgn(0, 0, width_, height_);
1026+ //SetWindowRgn(hwnd_, rgn, FALSE);
1027+
1028+ }
1029+ return std::is_same<proc_t,wndproc>::value?0:FALSE;
1030+ }
1031+
1032+ template <typename ProcType>
1033+ typename base_win32_window<ProcType>::result_t base_win32_window<ProcType>::on_create(CREATESTRUCT *p)
1034+ {
1035+ // DWM API
1036+ BOOL dwmEnable;
1037+ DwmIsCompositionEnabled (&dwmEnable);
1038+ if (dwmEnable) EnableBlurBehind(hwnd_);
1039+ //DwmEnableComposition(DWM_EC_DISABLECOMPOSITION );
1040+
1041+ // ウィンドウ全体を半透明にする
1042+ //SetLayeredWindowAttributes(
1043+ // hwnd_,
1044+ // RGB(0,0,0), // color key
1045+ // 100, // alpha value
1046+ // LWA_ALPHA | LWA_COLORKEY);
1047+
1048+ // ウィンドウの指定領域を半透明にする
1049+ // リージョンの設定
1050+ //HRGN rgn = CreateRectRgn(0, 0, width_, height_);
1051+ //SetWindowRgn(hwnd_, rgn, FALSE);
1052+
1053+ create_device();
1054+
1055+ timer_.start();
1056+ //show();
1057+ show();
1058+ text(title_);
1059+ return std::is_same<proc_t,wndproc>::value?0:FALSE;
1060+ }
1061+
1062+ template <typename ProcType>
1063+ typename base_win32_window<ProcType>::result_t base_win32_window<ProcType>::on_paint()
1064+ {
1065+ //{
1066+ sf::paint_struct p(hwnd_);
1067+ // gdi_object<HBRUSH> brush(::CreateSolidBrush(RGB(255,0,0)));
1068+ // {
1069+ // FillRect(p->hdc,&p->rcPaint,brush);
1070+ // }
1071+ //}
1072+ render();
1073+ return std::is_same<proc_t,wndproc>::value?0:FALSE;
1074+ }
1075+
1076+ template <typename ProcType>
1077+ void base_win32_window<ProcType>::render()
1078+ {
1079+
1080+ if(init_)
1081+ {
1082+ static float rot = 0.0f;
1083+
1084+ float color[4] = { 0.0f, 0.0f, 0.0f, 0.5f };
1085+
1086+ // 描画ターゲットのクリア
1087+ d3d_context_->ClearRenderTargetView(view_.Get(),color);
1088+ // 深度バッファのクリア
1089+ d3d_context_->ClearDepthStencilView(depth_view_.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0 );
1090+
1091+ // 色の変更
1092+ mesh_color_.x = 1.0f;
1093+ mesh_color_.y = 1.0f;
1094+ mesh_color_.z = 1.0f;
1095+
1096+ // 定数更新
1097+
1098+ cb_changes_every_frame cb;
1099+
1100+ mat_world_ = XMMatrixIdentity();
1101+// mat_world_._11 = 2.0f / width_;
1102+ mat_world_.r[0].m128_f32[0] = 2.0f / width_;
1103+ // mat_world_._22 = 2.0f / height_ * -1.0f;
1104+ mat_world_.r[1].m128_f32[1] = 2.0f / height_ * -1.0f;
1105+// mat_world_._41 = -1.0f;
1106+ mat_world_.r[3].m128_f32[0] = -1.0f;
1107+// mat_world_._42 = 1.0f;
1108+ mat_world_.r[3].m128_f32[1] = 1.0f;
1109+ mat_world_ *= XMMatrixRotationX(rot);
1110+ rot += 0.005f;
1111+ cb.mWorld = XMMatrixTranspose(mat_world_);
1112+ cb.vLightColor = mesh_color_;
1113+ d3d_context_->UpdateSubresource( cb_changes_every_frame_.Get(), 0, NULL, &cb, 0, 0 );
1114+
1115+ // 四角形
1116+ d3d_context_->VSSetShader( v_shader_.Get(), NULL, 0 );
1117+ d3d_context_->VSSetConstantBuffers( 0, 1, cb_never_changes_.GetAddressOf() );
1118+ d3d_context_->VSSetConstantBuffers( 1, 1, cb_change_on_resize_.GetAddressOf() );
1119+ d3d_context_->VSSetConstantBuffers( 2, 1, cb_changes_every_frame_.GetAddressOf() );
1120+ d3d_context_->PSSetShader( p_shader_.Get(), NULL, 0 );
1121+ d3d_context_->PSSetConstantBuffers( 2, 1, cb_changes_every_frame_.GetAddressOf() );
1122+ d3d_context_->PSSetShaderResources( 0, 1, shader_res_view_.GetAddressOf() );
1123+ d3d_context_->PSSetSamplers( 0, 1, sampler_state_.GetAddressOf() );
1124+
1125+ d3d_context_->DrawIndexed( 6, 0, 0 );
1126+
1127+ // 画面に転送
1128+ IDXGISurface1Ptr surface;
1129+ THROW_IF_ERR(back_buffer_.As<IDXGISurface1>(&surface));
1130+ HDC sdc;
1131+ THROW_IF_ERR(surface->GetDC( FALSE, &sdc ));
1132+
1133+ //get_dc ddc(hwnd_);
1134+ get_window_dc ddc(hwnd_);
1135+// RECT rc;
1136+// GetWindowRect(hwnd_,&rc);
1137+/* POINT wnd_pos = {rc.left,rc.top};
1138+ SIZE wnd_size = {width_,height_};
1139+ */
1140+ //BLENDFUNCTION blend;
1141+ // blend.BlendOp = AC_SRC_OVER;
1142+ // blend.BlendFlags = 0;
1143+ // blend.SourceConstantAlpha = 128; // 不透明度(レイヤードウィンドウ全体のアルファ値)
1144+ // blend.AlphaFormat = AC_SRC_ALPHA;
1145+ // デバイスコンテキストにおけるレイヤの位置
1146+ POINT po;
1147+ po.x = po.y = 0;
1148+ BOOL err;
1149+ err = BitBlt(ddc.get(),0,0,width_,height_,sdc,0,0,SRCCOPY);
1150+// err = AlphaBlend(ddc.get(),0,0,width_,height_,sdc,0,0,width_,height_,blend);
1151+ //err = UpdateLayeredWindow(hwnd_, ddc.get(), &wnd_pos, &wnd_size, sdc, &po, RGB(255,0,0), &blend, ULW_ALPHA | ULW_COLORKEY );
1152+ BOOST_ASSERT(err == TRUE);
1153+ surface->ReleaseDC( NULL);
1154+ surface.Reset();
1155+ // OMステージに登録する
1156+ d3d_context_->OMSetRenderTargets( 1, view_.GetAddressOf(), depth_view_.Get() );
1157+ }
1158+
1971159 }
1981160
199- template struct base_win32_window<WNDPROC>;
200- template struct base_win32_window<DLGPROC>;
1161+ template <typename ProcType>
1162+ typename base_win32_window<ProcType>::result_t base_win32_window<ProcType>::on_dwm_composition_changed()
1163+ {
1164+ BOOL enabled;
1165+ DwmIsCompositionEnabled(&enabled);
1166+ if(enabled)
1167+ {
1168+ EnableBlurBehind(hwnd_);
1169+ }
1170+ return std::is_same<proc_t,wndproc>::value?0:FALSE;
1171+ }
1172+ template struct base_win32_window<wndproc>;
1173+ template struct base_win32_window<dlgproc>;
2011174
2021175 //ID2D1FactoryPtr base_win32_window::factory() { return impl_->factory();};
2031176 //ID2D1HwndRenderTargetPtr base_win32_window::render_target() { return impl_->render_target();};
@@ -205,7 +1178,7 @@ namespace sf
2051178
2061179 subclass_window::subclass_window(HWND hwnd)
2071180 : base_win32_window (
208- std::wstring(L""),std::wstring(L""),false,0,0
1181+ std::wstring(L""),std::wstring(L""),false,0,0
2091182 ),is_subclassed_(false)
2101183 {
2111184 attach(hwnd);
@@ -213,7 +1186,7 @@ namespace sf
2131186
2141187 subclass_window::subclass_window()
2151188 : base_win32_window (
216- std::wstring(L""),std::wstring(L""),false,0,0
1189+ std::wstring(L""),std::wstring(L""),false,0,0
2171190 ),is_subclassed_(false)
2181191 {
2191192
--- a/wasapi2/sf_windows.h
+++ b/wasapi2/sf_windows.h
@@ -2,15 +2,16 @@
22 /*
33 */
44 // Windows Header Files:
5+#define XBYAK64
56 #include "exception.h"
67 #include "base_window.h"
78 #include "dpi.h"
8-#define XBYAK64
99 #include "xbyak.h"
1010 #include "windows.h"
1111 #include "windowsx.h"
1212 #include "CommCtrl.h"
1313 #include <type_traits>
14+#include "timer.h"
1415 //#include <boost/type_traits/is_same.hpp>
1516 // DLLのリンク
1617 #pragma comment(lib,"d2d1.lib")
@@ -20,80 +21,80 @@
2021
2122 //#include "input.h"
2223
24+
2325 // Direct Write
2426
25-_COM_SMARTPTR_TYPEDEF(IDWriteFactory , __uuidof(IDWriteFactory));
26-_COM_SMARTPTR_TYPEDEF(IDWriteGdiInterop , __uuidof(IDWriteGdiInterop));
27-_COM_SMARTPTR_TYPEDEF(IDWriteFontFace , __uuidof(IDWriteFontFace));
28-_COM_SMARTPTR_TYPEDEF(IDWriteFont , __uuidof(IDWriteFont));
29-_COM_SMARTPTR_TYPEDEF(IDWriteFontFamily , __uuidof(IDWriteFontFamily));
30-_COM_SMARTPTR_TYPEDEF(IDWriteFontCollection , __uuidof(IDWriteFontCollection));
31-_COM_SMARTPTR_TYPEDEF(IDWriteLocalizedStrings , __uuidof(IDWriteLocalizedStrings));
32-_COM_SMARTPTR_TYPEDEF(IDWriteTextFormat, __uuidof(IDWriteTextFormat));
33-_COM_SMARTPTR_TYPEDEF(IDWriteTextLayout, __uuidof(IDWriteTextLayout));
34-_COM_SMARTPTR_TYPEDEF(IDWriteFontFile,__uuidof(IDWriteTextLayout));
35-//_COM_SMARTPTR_TYPEDEF(IDWriteFontFile,__uuidof(IDWriteTextLayout));
27+_WRL_PTR_TYPEDEF(IDWriteFactory);
28+_WRL_PTR_TYPEDEF(IDWriteGdiInterop);
29+_WRL_PTR_TYPEDEF(IDWriteFontFace);
30+_WRL_PTR_TYPEDEF(IDWriteFont);
31+_WRL_PTR_TYPEDEF(IDWriteFontFamily);
32+_WRL_PTR_TYPEDEF(IDWriteFontCollection);
33+_WRL_PTR_TYPEDEF(IDWriteLocalizedStrings);
34+_WRL_PTR_TYPEDEF(IDWriteTextFormat);
35+_WRL_PTR_TYPEDEF(IDWriteTextLayout);
36+_WRL_PTR_TYPEDEF(IDWriteFontFile);
37+//_WRL_PTR_TYPEDEF(IDWriteFontFile);
3638
3739 // Direct2D
3840
39-_COM_SMARTPTR_TYPEDEF(ID2D1Factory,__uuidof(ID2D1Factory));
40-_COM_SMARTPTR_TYPEDEF(ID2D1HwndRenderTarget , __uuidof(ID2D1HwndRenderTarget));
41-_COM_SMARTPTR_TYPEDEF(ID2D1BitmapRenderTarget , __uuidof(ID2D1BitmapRenderTarget));
42-_COM_SMARTPTR_TYPEDEF(ID2D1GdiInteropRenderTarget , __uuidof(ID2D1GdiInteropRenderTarget));
43-_COM_SMARTPTR_TYPEDEF(ID2D1DCRenderTarget , __uuidof(ID2D1DCRenderTarget));
44-_COM_SMARTPTR_TYPEDEF(ID2D1PathGeometry , __uuidof(ID2D1PathGeometry));
45-_COM_SMARTPTR_TYPEDEF(ID2D1LinearGradientBrush , __uuidof(ID2D1LinearGradientBrush));
46-_COM_SMARTPTR_TYPEDEF(ID2D1GradientStopCollection , __uuidof(ID2D1GradientStopCollection));
47-_COM_SMARTPTR_TYPEDEF(ID2D1SolidColorBrush , __uuidof(ID2D1SolidColorBrush));
48-_COM_SMARTPTR_TYPEDEF(ID2D1BitmapBrush , __uuidof(ID2D1BitmapBrush));
49-_COM_SMARTPTR_TYPEDEF(ID2D1Bitmap , __uuidof(ID2D1Bitmap));
41+_WRL_PTR_TYPEDEF(ID2D1Factory);
42+_WRL_PTR_TYPEDEF(ID2D1HwndRenderTarget);
43+_WRL_PTR_TYPEDEF(ID2D1BitmapRenderTarget);
44+_WRL_PTR_TYPEDEF(ID2D1GdiInteropRenderTarget);
45+_WRL_PTR_TYPEDEF(ID2D1DCRenderTarget);
46+_WRL_PTR_TYPEDEF(ID2D1PathGeometry);
47+_WRL_PTR_TYPEDEF(ID2D1LinearGradientBrush);
48+_WRL_PTR_TYPEDEF(ID2D1GradientStopCollection);
49+_WRL_PTR_TYPEDEF(ID2D1SolidColorBrush);
50+_WRL_PTR_TYPEDEF(ID2D1BitmapBrush);
51+_WRL_PTR_TYPEDEF(ID2D1Bitmap);
5052
5153 // WIC
5254
53-_COM_SMARTPTR_TYPEDEF(IWICImagingFactory, __uuidof(IWICImagingFactory));
54-_COM_SMARTPTR_TYPEDEF(IWICBitmapDecoder,__uuidof(IWICBitmapDecoder));
55-_COM_SMARTPTR_TYPEDEF(IWICBitmapFrameDecode,__uuidof(IWICBitmapFrameDecode));
56-_COM_SMARTPTR_TYPEDEF(IWICStream,__uuidof(IWICStream));
57-_COM_SMARTPTR_TYPEDEF(IWICFormatConverter,__uuidof(IWICFormatConverter));
58-_COM_SMARTPTR_TYPEDEF(IWICBitmapScaler,__uuidof(IWICBitmapScaler));
59-_COM_SMARTPTR_TYPEDEF(ITaskbarList3,__uuidof(ITaskbarList3));
55+_WRL_PTR_TYPEDEF(IWICImagingFactory);
56+_WRL_PTR_TYPEDEF(IWICBitmapDecoder);
57+_WRL_PTR_TYPEDEF(IWICBitmapFrameDecode);
58+_WRL_PTR_TYPEDEF(IWICStream);
59+_WRL_PTR_TYPEDEF(IWICFormatConverter);
60+_WRL_PTR_TYPEDEF(IWICBitmapScaler);
61+_WRL_PTR_TYPEDEF(ITaskbarList3);
6062
6163 // DXGI
6264
63-_COM_SMARTPTR_TYPEDEF(IDXGISwapChain,__uuidof(IDXGISwapChain));
64-_COM_SMARTPTR_TYPEDEF(IDXGIFactory1,__uuidof(IDXGIFactory1));
65-_COM_SMARTPTR_TYPEDEF(IDXGIAdapter1,__uuidof(IDXGIAdapter1));
66-_COM_SMARTPTR_TYPEDEF(IDXGIDevice1,__uuidof(IDXGIDevice1));
67-_COM_SMARTPTR_TYPEDEF(IDXGIKeyedMutex,__uuidof(IDXGIKeyedMutex));
68-_COM_SMARTPTR_TYPEDEF(IDXGIObject,__uuidof(IDXGIObject));
69-_COM_SMARTPTR_TYPEDEF(IDXGIDeviceSubObject,__uuidof(IDXGIDeviceSubObject));
70-_COM_SMARTPTR_TYPEDEF(IDXGISurface1,__uuidof(IDXGISurface1));
71-_COM_SMARTPTR_TYPEDEF(IDXGIOutput,__uuidof(IDXGIOutput));
72-//_COM_SMARTPTR_TYPEDEF(IDXGI,__uuidof(IDXGI));
73-//_COM_SMARTPTR_TYPEDEF(IDXGI,__uuidof(IDXGI));
65+_WRL_PTR_TYPEDEF(IDXGISwapChain);
66+_WRL_PTR_TYPEDEF(IDXGIFactory1);
67+_WRL_PTR_TYPEDEF(IDXGIAdapter1);
68+_WRL_PTR_TYPEDEF(IDXGIDevice1);
69+_WRL_PTR_TYPEDEF(IDXGIKeyedMutex);
70+_WRL_PTR_TYPEDEF(IDXGIObject);
71+_WRL_PTR_TYPEDEF(IDXGIDeviceSubObject);
72+_WRL_PTR_TYPEDEF(IDXGISurface1);
73+_WRL_PTR_TYPEDEF(IDXGIOutput);
74+//_WRL_PTR_TYPEDEF(IDXGI);
75+//_WRL_PTR_TYPEDEF(IDXGI);
7476
7577 // Direct3D
7678
77-_COM_SMARTPTR_TYPEDEF(ID3D11Device,__uuidof(ID3D11Device));
78-_COM_SMARTPTR_TYPEDEF(ID3D11DeviceContext,__uuidof(ID3D11DeviceContext));
79-_COM_SMARTPTR_TYPEDEF(ID3D11RenderTargetView,__uuidof(ID3D11RenderTargetView));
80-_COM_SMARTPTR_TYPEDEF(ID3D11DepthStencilView,__uuidof(ID3D11DepthStencilView));
81-_COM_SMARTPTR_TYPEDEF(ID3D11VertexShader,__uuidof(ID3D11VertexShader));
82-_COM_SMARTPTR_TYPEDEF(ID3D11PixelShader,__uuidof(ID3D11PixelShader));
83-_COM_SMARTPTR_TYPEDEF(ID3D11InputLayout,__uuidof(ID3D11InputLayout));
84-_COM_SMARTPTR_TYPEDEF(ID3D11Buffer,__uuidof(ID3D11Buffer));
85-_COM_SMARTPTR_TYPEDEF(ID3D11Texture2D,__uuidof(ID3D11Texture2D));
86-_COM_SMARTPTR_TYPEDEF(ID3DBlob,__uuidof(ID3DBlob));
87-_COM_SMARTPTR_TYPEDEF(ID3D11ShaderResourceView,__uuidof(ID3D11ShaderResourceView));
88-_COM_SMARTPTR_TYPEDEF(ID3D11SamplerState,__uuidof(ID3D11SamplerState));
89-
90-
79+_WRL_PTR_TYPEDEF(ID3D11Device);
80+_WRL_PTR_TYPEDEF(ID3D11DeviceContext);
81+_WRL_PTR_TYPEDEF(ID3D11RenderTargetView);
82+_WRL_PTR_TYPEDEF(ID3D11DepthStencilView);
83+_WRL_PTR_TYPEDEF(ID3D11VertexShader);
84+_WRL_PTR_TYPEDEF(ID3D11PixelShader);
85+_WRL_PTR_TYPEDEF(ID3D11InputLayout);
86+_WRL_PTR_TYPEDEF(ID3D11Buffer);
87+_WRL_PTR_TYPEDEF(ID3D11Texture2D);
88+_WRL_PTR_TYPEDEF(ID3DBlob);
89+_WRL_PTR_TYPEDEF(ID3D11ShaderResourceView);
90+_WRL_PTR_TYPEDEF(ID3D11SamplerState);
91+_WRL_PTR_TYPEDEF(ID3D11Resource);
9192
9293 namespace sf{
9394
94- /* inline template <class Exc = win32_error_exception> void throw_if_err<>()(HRESULT hr)
95+ /* inline template <class Exc = win32_error_exception> void throw_if_err<>()(HRESULT hr)
9596 {
96- if(hr != S_OK){throw Exc(hr);}
97+ if(hr != S_OK){throw Exc(hr);}
9798 };*/
9899
99100
@@ -173,6 +174,15 @@ namespace sf{
173174 HWND hwnd_;
174175 };
175176
177+ struct get_window_dc {
178+ get_window_dc(HWND hwnd) : hwnd_(hwnd),hdc_(GetWindowDC(hwnd)) {}
179+ HDC get(){return hdc_;}
180+ ~get_window_dc(){::ReleaseDC(hwnd_,hdc_);}
181+ private:
182+ HDC hdc_;
183+ HWND hwnd_;
184+ };
185+
176186 struct compatible_dc {
177187 compatible_dc(HDC hdc) : hdc_(::CreateCompatibleDC(hdc)){};
178188 ~compatible_dc(){::DeleteDC(hdc_);};
@@ -225,9 +235,9 @@ namespace sf{
225235 struct HBITMAP_deleter {
226236 typedef HBITMAP pointer;
227237 void operator ()(HBITMAP handle) {
228- if (handle) {
229- ::DeleteObject(handle);
230- }
238+ if (handle) {
239+ ::DeleteObject(handle);
240+ }
231241 }
232242 };
233243
@@ -259,7 +269,7 @@ namespace sf{
259269
260270 // GDI オブジェクト管理テンプレート
261271 template <class GdiObject>
262- struct gdi_object: boost::noncopyable
272+ struct gdi_object: boost::noncopyable
263273 {
264274 explicit gdi_object(GdiObject obj) : gdiobj_(obj) {}
265275 ~gdi_object(){::DeleteObject(gdiobj_);}
@@ -277,7 +287,7 @@ namespace sf{
277287 HDC dc_;
278288 HGDIOBJ o_;
279289 };
280-
290+
281291 // Direct2D BeginDrawヘルパ関数
282292 template <typename T >
283293 struct begin_draw
@@ -286,7 +296,7 @@ namespace sf{
286296
287297 begin_draw(T& render_target,err_handler_type& handler)
288298 : render_target_(render_target) ,
289- is_end_(false),handler_(handler)
299+ is_end_(false),handler_(handler)
290300 {render_target->BeginDraw();}
291301
292302 ~begin_draw(){
@@ -310,30 +320,41 @@ namespace sf{
310320 bool left_button_,middle_button_,right_button_;
311321 };
312322
313- // 普通はDefWindowProcW
314- template <typename ProcType>
315- inline LRESULT def_wnd_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
323+
324+ // ウィンドウプロシージャの識別用クラス
325+ struct wndproc
316326 {
317- return ::DefWindowProcW(hwnd,message,wParam,lParam);
327+ typedef WNDPROC proc_type;
328+ typedef LRESULT return_type;
329+ static inline return_type def_wnd_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
330+ {
331+ return ::DefWindowProcW(hwnd,message,wParam,lParam);
332+ }
318333 };
319334
320- // DLFPROCはTRUEを返す。
321- template <>
322- inline LRESULT def_wnd_proc<DLGPROC>(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
335+ // ダイアログプロシージャの識別用クラス
336+ struct dlgproc
323337 {
324- return FALSE;
338+ typedef DLGPROC proc_type;
339+ typedef INT_PTR return_type;
340+ static inline return_type def_wnd_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
341+ {
342+ return FALSE;
343+ }
325344 };
326345
327346 /** window ベースクラス */
328- template <typename ProcType = WNDPROC>
347+ template <typename ProcType = wndproc>
329348 struct base_win32_window : public base_window
330349 {
331350 typedef ProcType proc_t;
351+ typedef typename proc_t::return_type result_t;
352+// typedef proc_t::return_type result_t;
332353
333354 operator HWND() const {return hwnd_;};
334-
355+
335356 virtual void * raw_handle() const {return hwnd_;};
336-// virtual void show(uint32_t show_flag);
357+ // virtual void show(uint32_t show_flag);
337358
338359 virtual void show() {
339360 ::ShowWindow(hwnd_,SW_SHOW);
@@ -374,17 +395,24 @@ namespace sf{
374395 ::MessageBox(hwnd_,text.c_str(),caption.c_str(),type);
375396 }
376397
377-
378398 virtual void update();
379399
400+ virtual void create_device_independent_resources();
401+ virtual void create_device();
402+ virtual void create_swapchain_dependent_resources();
403+
404+ virtual void discard_swapchain_dependent_resources();
405+ virtual void discard_device();
406+ virtual void discard_device_independant_resources();
407+
380408 protected:
381-
409+
382410 base_win32_window(
383411 const std::wstring& title,
384412 const std::wstring& name,bool fit_to_display,
385413 float width,float height);
386414
387-
415+
388416 ~base_win32_window();
389417
390418 void register_class (
@@ -400,7 +428,16 @@ namespace sf{
400428
401429 /** デフォルト設定 */
402430 void register_class();
403- void create_window();
431+ void create_window(HWND parent = NULL);
432+
433+ void calc_client_size()
434+ {
435+ //クライアント領域の現在の幅、高さを求める
436+ RECT rc;
437+ GetClientRect( hwnd_, &rc );
438+ client_width_ = rc.right - rc.left;
439+ client_height_ = rc.bottom - rc.top;
440+ }
404441 public:
405442 // SetWindowLong API
406443 void set_long(int index,long data)
@@ -447,52 +484,87 @@ namespace sf{
447484 ::EnableWindow(GetDlgItem(hwnd,id),enable?TRUE:FALSE);
448485 };
449486
450- virtual LRESULT window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam);
451- virtual LRESULT other_window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
487+ virtual result_t window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam);
488+ virtual result_t other_window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
452489 {
453- return def_wnd_proc<ProcType>(hwnd,message,wParam,lParam);
490+ return proc_t::def_wnd_proc(hwnd,message,wParam,lParam);
454491 };
455-
492+
456493 // デフォルトウィンドウメッセージハンドラ
457- virtual LRESULT on_nccreate(CREATESTRUCT *p) { return std::is_same<proc_t,WNDPROC>::value?1:FALSE;}
458- virtual LRESULT on_create(CREATESTRUCT *p) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
459- virtual LRESULT on_init_dialog(HWND default_focus_ctrl,LPARAM data) {return TRUE;}
460- virtual LRESULT on_size(uint32_t flag,uint32_t width,uint32_t height) {return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
494+ virtual result_t on_nccreate(CREATESTRUCT *p) ;//{ return std::is_same<proc_t,wndproc>::value?1:FALSE;}
495+ virtual result_t on_create(CREATESTRUCT *p); //{ return std::is_same<proc_t,wndproc>::value?0:FALSE;}
496+ virtual result_t on_init_dialog(HWND default_focus_ctrl,LPARAM data) {return TRUE;}
497+ virtual result_t on_size(uint32_t flag,uint32_t width,uint32_t height);//{return std::is_same<proc_t,wndproc>::value?0:FALSE; }
461498 //virtual LRESULT
462- virtual LRESULT on_paint() {return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
463- virtual LRESULT on_display_change(uint32_t bpp,uint32_t h_resolution,uint32_t v_resolution) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
464- virtual LRESULT on_erase_backgroud(HDC dc) {return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
465- virtual LRESULT on_hscroll(uint32_t state,uint32_t position,HWND ctrl_hwnd) {return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
466- virtual LRESULT on_vscroll(uint32_t state,uint32_t position,HWND ctrl_hwnd) {return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
467- virtual LRESULT on_left_mouse_button_down(uint32_t mouse_key,int x,int y ) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
468- virtual LRESULT on_left_mouse_button_up(uint32_t mouse_key,int x,int y) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
469- virtual LRESULT on_left_mouse_button_double_click(uint32_t mouse_key,int x,int y) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
470- virtual LRESULT on_mouse_move(uint32_t mouse_key,int x,int y) {return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
471- virtual LRESULT on_mouse_wheel(uint32_t mouse_key,int delta,int x,int y) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
499+ virtual result_t on_paint();
500+ virtual result_t on_display_change(uint32_t bpp,uint32_t h_resolution,uint32_t v_resolution) { invalidate_rect();return std::is_same<proc_t,wndproc>::value?0:FALSE;}
501+ virtual result_t on_erase_backgroud(HDC dc) {return std::is_same<proc_t,wndproc>::value?1:TRUE;}
502+ virtual result_t on_hscroll(uint32_t state,uint32_t position,HWND ctrl_hwnd) {return std::is_same<proc_t,wndproc>::value?0:FALSE;}
503+ virtual result_t on_vscroll(uint32_t state,uint32_t position,HWND ctrl_hwnd) {return std::is_same<proc_t,wndproc>::value?0:FALSE;}
504+ virtual result_t on_left_mouse_button_down(uint32_t mouse_key,int x,int y ) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
505+ virtual result_t on_left_mouse_button_up(uint32_t mouse_key,int x,int y) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
506+ virtual result_t on_left_mouse_button_double_click(uint32_t mouse_key,int x,int y) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
507+ virtual result_t on_mouse_move(uint32_t mouse_key,int x,int y) {return std::is_same<proc_t,wndproc>::value?0:FALSE; }
508+ virtual result_t on_mouse_wheel(uint32_t mouse_key,int delta,int x,int y) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
472509 //virtual bool on_mouse_enter(uint32_t mouse_key,int x,int y) { return false; }
473- virtual LRESULT on_mouse_leave() { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
474- virtual LRESULT on_destroy(){return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
475- virtual LRESULT on_close(){return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
476- virtual LRESULT on_set_cursor() { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
477- virtual LRESULT on_key_down(uint32_t vkey,uint32_t ext_key,uint32_t repeat) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
478- virtual LRESULT on_key_up(uint32_t vkey,uint32_t ext_key,uint32_t repeat) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
479- virtual LRESULT on_app_command(uint32_t command,uint32_t device,uint32_t keystate) {return std::is_same<proc_t,WNDPROC>::value?0:FALSE;}
480- virtual LRESULT on_command(uint32_t wparam, uint32_t lparam) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
481- virtual LRESULT on_timer(uint32_t timer_id) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
482- virtual LRESULT on_notify(NMHDR* nmhdr) { return std::is_same<proc_t,WNDPROC>::value?0:FALSE; }
483-
484- protected:
485- static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
510+ virtual result_t on_mouse_leave() { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
511+ virtual result_t on_destroy(){
512+ //::PostQuitMessage(0);
513+ return std::is_same<proc_t,wndproc>::value?0:FALSE;
514+ }
515+
516+ virtual result_t on_close()
517+ {
518+ discard_device();
519+ // Windowの破棄
520+ BOOL ret(::DestroyWindow(hwnd_));
521+ BOOST_ASSERT(ret != 0);
522+// return TRUE;
523+ return std::is_same<proc_t,wndproc>::value?1:TRUE;
524+ }
525+
526+ virtual result_t on_set_cursor() { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
527+ virtual result_t on_key_down(uint32_t vkey,uint32_t ext_key,uint32_t repeat) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
528+ virtual result_t on_key_up(uint32_t vkey,uint32_t ext_key,uint32_t repeat) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
529+ virtual result_t on_app_command(uint32_t command,uint32_t device,uint32_t keystate) {return std::is_same<proc_t,wndproc>::value?0:FALSE;}
530+ virtual result_t on_command(uint32_t wparam, uint32_t lparam) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
531+ virtual result_t on_timer(uint32_t timer_id) {
532+ //::InvalidateRect(hwnd_,NULL,FALSE);
533+ render();
534+ return std::is_same<proc_t,wndproc>::value?0:FALSE;
535+ }
536+ virtual result_t on_notify(NMHDR* nmhdr) { return std::is_same<proc_t,wndproc>::value?0:FALSE; }
537+ virtual result_t on_dwm_composition_changed();
538+ virtual void render();
539+ protected:
540+ void get_dxgi_information();
541+
542+ // Window生成後呼ばれる関数
543+ // WM_NCCREATEメッセージの時にthunkに切り替える
544+ static result_t CALLBACK start_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
545+ {
546+ if(message == WM_NCCREATE)
547+ {
548+ LPCREATESTRUCT param = reinterpret_cast<LPCREATESTRUCT>(lParam);
549+ base_win32_window* ptr = reinterpret_cast<base_win32_window*>(param->lpCreateParams);
550+ ptr->hwnd_ = hwnd;
551+ // ウィンドウプロシージャをインスタンスと結び付けるthunkプロシージャに入れ替える
552+ LONG_PTR r = SetWindowLongPtr(hwnd,GWLP_WNDPROC,reinterpret_cast<LONG_PTR>(ptr->thunk_proc_));
553+ assert(r == reinterpret_cast<LONG_PTR>(&start_wnd_proc));
554+ return ptr->window_proc(hwnd,message,wParam,lParam);
555+ }
556+ return ::DefWindowProcW(hwnd,message,wParam,lParam);
557+ };
558+
559+ static result_t CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
486560 {
487561 base_win32_window* ptr = reinterpret_cast<base_win32_window*>(hwnd);
488- hwnd = ptr->hwnd_;
489- // TODO: メッセージハンドラを拡張可能にする。
490- return ptr->window_proc(hwnd,message,wParam,lParam);
562+ return ptr->window_proc(ptr->hwnd_,message,wParam,lParam);
491563 };
492564
493565 // thisとhwndをつなぐthunkクラス
494566 struct hwnd_this_thunk : public Xbyak::CodeGenerator {
495- hwnd_this_thunk(base_win32_window* impl,ProcType proc)
567+ hwnd_this_thunk(base_win32_window* impl,typename proc_t::proc_type proc)
496568 {
497569 // rcxにhwndが格納されているので、それをimpl->hwndに保存
498570 // mov(ptr[&(impl->hwnd_)],rcx); // <-- エラー発生部分
@@ -507,6 +579,16 @@ namespace sf{
507579 }
508580 };
509581
582+ void update_window_size()
583+ {
584+ RECT r;
585+ GetWindowRect(hwnd_,&r);
586+ width_ = r.right - r.left;
587+ height_ = r.bottom - r.top;
588+ }
589+
590+ void init_view_matrix();
591+
510592 HWND hwnd_;
511593 hwnd_this_thunk thunk_;
512594 std::wstring title_;
@@ -514,13 +596,67 @@ namespace sf{
514596 float width_,height_;
515597 bool fit_to_display_;
516598 std::shared_ptr<sf::window_class_ex> wnd_class_;
517- ProcType thunk_proc_;
599+ typename proc_t::proc_type thunk_proc_;
518600 dpi dpi_;
519601 WINDOWPLACEMENT wp_;
520- };
521-
522- typedef base_win32_window<> base_win32_window_t;
523- typedef base_win32_window<DLGPROC> base_win32_dialog_t;
602+ bool init_;
603+
604+ //ID2D1FactoryPtr factory_;
605+ //ID2D1HwndRenderTargetPtr render_target_;
606+ //IDWriteFactoryPtr write_factory_;
607+ //IWICImagingFactoryPtr wic_imaging_factory_;
608+ //IDWriteTextFormatPtr write_text_format_;
609+
610+ IDXGIFactory1Ptr dxgi_factory_;
611+ IDXGIAdapter1Ptr adapter_;
612+ IDXGIOutputPtr output_;
613+ ID3D11DevicePtr d3d_device_;
614+ ID3D11DeviceContextPtr d3d_context_;
615+ ID3D11Texture2DPtr texture_;
616+ ID3D11RenderTargetViewPtr view_;
617+ ID3D11Texture2DPtr depth_texture_;
618+ ID3D11DepthStencilViewPtr depth_view_;
619+ ID3D11VertexShaderPtr v_shader_;
620+ ID3D11InputLayoutPtr input_layout_;
621+ ID3D11PixelShaderPtr p_shader_;
622+ ID3D11BufferPtr v_buffer_;
623+ ID3D11BufferPtr i_buffer_;
624+ ID3D11BufferPtr cb_never_changes_;
625+ ID3D11BufferPtr cb_change_on_resize_;
626+ ID3D11BufferPtr cb_changes_every_frame_;
627+ ID3D11ShaderResourceViewPtr shader_res_view_;
628+ ID3D11SamplerStatePtr sampler_state_;
629+ ID3D11Texture2DPtr back_buffer_;
630+
631+ //ID3D11SamplerStatePtr cube_sampler_state_;
632+ //ID3D11Texture2DPtr cube_texture_;
633+ //ID3D11Texture2DPtr cube_depth_texture_;
634+ //ID3D11ShaderResourceViewPtr cube_shader_res_view_;
635+ //ID3D11RenderTargetViewPtr cube_view_;
636+ //ID3D11DepthStencilViewPtr cube_depth_view_;
637+
638+ DXGI_MODE_DESC actual_desc_;
639+ //IDXGISwapChainPtr swap_chain_;
640+ std::wstring dxgi_info_;
641+
642+
643+
644+ DirectX::XMMATRIX mat_world_;
645+ DirectX::XMMATRIX mat_view_;
646+ DirectX::XMMATRIX mat_projection_;
647+ DirectX::XMMATRIX cube_mat_projection_;
648+
649+ DirectX::XMFLOAT4 mesh_color_;
650+ float client_width_,client_height_;
651+
652+ timer timer_;
653+
654+ // __declspec ( thread ) static std::queue<proc_t::proc_type> ptrs_ ;// thread local storage
655+
656+ };
657+
658+ typedef base_win32_window<> base_win32_window_t;
659+ typedef base_win32_window<dlgproc> base_win32_dialog_t;
524660
525661 /// サブクラスウィンドウ
526662 struct subclass_window : public base_win32_window_t
@@ -530,7 +666,7 @@ namespace sf{
530666 void attach(HWND hwnd);
531667 void detatch();
532668 ~subclass_window();
533- virtual LRESULT window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
669+ virtual result_t window_proc(HWND hwnd,uint32_t message, WPARAM wParam, LPARAM lParam)
534670 {
535671 return CallWindowProc(proc_backup_,hwnd,message,wParam,lParam);
536672 };
@@ -539,33 +675,33 @@ namespace sf{
539675 WNDPROC proc_backup_;
540676 };
541677
542-struct av_mm_thread_characteristics
543-{
544- av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
678+ struct av_mm_thread_characteristics
545679 {
546- handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
547- }
680+ av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
681+ {
682+ handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
683+ }
684+
685+ bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
686+
687+ ~av_mm_thread_characteristics()
688+ {
689+ ::AvRevertMmThreadCharacteristics(handle_);
690+ }
548691
549- bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
692+ private:
693+ std::wstring task_name_;
694+ uint32_t task_index_;
695+ HANDLE handle_;
696+ };
550697
551- ~av_mm_thread_characteristics()
698+ struct widget
552699 {
553- ::AvRevertMmThreadCharacteristics(handle_);
554- }
555-
556-private:
557- std::wstring task_name_;
558- uint32_t task_index_;
559- HANDLE handle_;
560-};
561-
562-struct widget
563-{
564- void draw();
565- float x_,y_;
566-};
567-
568-typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
569-typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;
570-
700+ void draw();
701+ float x_,y_;
702+ };
703+
704+ typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
705+ typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;
706+
571707 }
\ No newline at end of file
--- a/wasapi2/stdafx.h
+++ b/wasapi2/stdafx.h
@@ -104,18 +104,19 @@
104104
105105 #include "dxgi.h"
106106
107-// Direct3D
108-
109-#include "d3d11.h"
107+#include "d3d11_1.h"
108+#include <d3d11shader.h>
109+#include <DDSTextureLoader.h>
110110 //#include "d3dx11.h"
111111 //#include <d3dx11effect.h>
112112 //#include <d3dxGlobal.h>
113113 #include <d3dcompiler.h>
114-#include <DirectXMath.h>
114+#include "DirectXMath.h"
115+//#include <xnamath.h>
115116
116117 // Direct2D
117118
118-#include <d2d1.h>
119+#include <d2d1_1.h>
119120 #include <d2d1helper.h>
120121
121122 // Direct Write
@@ -141,3 +142,10 @@
141142 #include "logger.h"
142143 #include "dout.h"
143144 //#include "dxerr.h"
145+#include <wrl.h>
146+#using <windows.winmd>
147+#using <platform.winmd>
148+#include <ppl.h>
149+#include <ppltasks.h>
150+
151+#define _WRL_PTR_TYPEDEF(x) typedef Microsoft::WRL::ComPtr<x> x ## Ptr
--- a/wasapi2/taskbar.cpp
+++ b/wasapi2/taskbar.cpp
@@ -34,7 +34,7 @@ struct taskbar::impl
3434 }
3535
3636 void create() {
37- throw_if_err_()(taskbar_.CreateInstance(CLSID_TaskbarList));
37+ throw_if_err_()(CoCreateInstance(CLSID_TaskbarList,nullptr,CLSCTX::CLSCTX_INPROC_SERVER,__uuidof(ITaskbarList4),(LPVOID*)taskbar_.GetAddressOf()));
3838 }
3939 bool is_create() const
4040 {
@@ -69,7 +69,7 @@ struct taskbar::impl
6969 };
7070
7171 private:
72- _COM_SMARTPTR_TYPEDEF(ITaskbarList4,__uuidof(ITaskbarList4));
72+ _WRL_PTR_TYPEDEF(ITaskbarList4);
7373 ITaskbarList4Ptr taskbar_;
7474 };
7575
--- a/wasapi2/toplevel_window.cpp
+++ b/wasapi2/toplevel_window.cpp
@@ -68,149 +68,149 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
6868 namespace sf
6969 {
7070
71- HRESULT EnableBlurBehind(HWND hwnd)
72- {
73- HRESULT hr = S_OK;
74-
75- //Create and populate the BlurBehind structre
76- DWM_BLURBEHIND bb = {0};
77- //Enable Blur Behind and Blur Region;
78- bb.dwFlags = DWM_BB_ENABLE;
79- bb.fEnable = true;
80- bb.hRgnBlur = NULL;
81-
82- //Enable Blur Behind
83- hr = DwmEnableBlurBehindWindow(hwnd, &bb);
84- if (SUCCEEDED(hr))
85- {
86- //do more things
87- }
88- return hr;
89- }
90-
91- // 汎用情報格納用
92- struct mode_info
93- {
94- mode_info(const std::wstring& n,const std::wstring& d) : name(n),description(d) {}
95- std::wstring name;
96- std::wstring description;
97- };
98-
99- // ディスプレイモード
100- struct display_mode
101- {
102- display_mode(const std::wstring& n,const std::wstring& d) : name(n),description(d) {}
103- std::wstring name;
104- std::wstring description;
105- };
106-
107- std::vector<mode_info> display_modes =
108- boost::assign::list_of<mode_info>
109- (L"DXGI_FORMAT_UNKNOWN",L"フォーマットが不明")
110- (L"DXGI_FORMAT_R32G32B32A32_TYPELESS",L"4 成分、128 ビット型なしフォーマット 1")
111- (L"DXGI_FORMAT_R32G32B32A32_FLOAT",L"4 成分、128 ビット浮動小数点フォーマット 1")
112- (L"DXGI_FORMAT_R32G32B32A32_UINT",L"4 成分、128 ビット符号なし整数フォーマット 1")
113- (L"DXGI_FORMAT_R32G32B32A32_SINT",L"4 成分、128 ビット符号付き整数フォーマット 1")
114- (L"DXGI_FORMAT_R32G32B32_TYPELESS",L"3 成分、96 ビット型なしフォーマット")
115- (L"DXGI_FORMAT_R32G32B32_FLOAT",L"3 成分、96 ビット浮動小数点フォーマット")
116- (L"DXGI_FORMAT_R32G32B32_UINT",L"3 成分、96 ビット符号なし整数フォーマット")
117- (L"DXGI_FORMAT_R32G32B32_SINT",L"3 成分、96 ビット符号付き整数フォーマット")
118- (L"DXGI_FORMAT_R16G16B16A16_TYPELESS",L"4 成分、64 ビット型なしフォーマット")
119- (L"DXGI_FORMAT_R16G16B16A16_FLOAT",L"4 成分、64 ビット浮動小数点フォーマット")
120- (L"DXGI_FORMAT_R16G16B16A16_UNORM",L"4 成分、64 ビット符号なし整数フォーマット")
121- (L"DXGI_FORMAT_R16G16B16A16_UINT",L"4 成分、64 ビット符号なし整数フォーマット")
122- (L"DXGI_FORMAT_R16G16B16A16_SNORM",L"4 成分、64 ビット符号付き整数フォーマット")
123- (L"DXGI_FORMAT_R16G16B16A16_SINT",L"4 成分、64 ビット符号付き整数フォーマット")
124- (L"DXGI_FORMAT_R32G32_TYPELESS",L"2 成分、64 ビット型なしフォーマット")
125- (L"DXGI_FORMAT_R32G32_FLOAT",L"2 成分、64 ビット浮動小数点フォーマット")
126- (L"DXGI_FORMAT_R32G32_UINT",L"2 成分、64 ビット符号なし整数フォーマット")
127- (L"DXGI_FORMAT_R32G32_SINT",L"2 成分、64 ビット符号付き整数フォーマット")
128- (L"DXGI_FORMAT_R32G8X24_TYPELESS",L"2 成分、64 ビット型なしフォーマット")
129- (L"DXGI_FORMAT_D32_FLOAT_S8X24_UINT",L"32 ビット浮動小数点成分、および 2 つの符号なし整数成分です (追加の 32 ビットを含む)。")
130- (L"DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS",L"32 ビット浮動小数点成分、および 2 つの型なし成分です (追加の 32 ビットを含む)。")
131- (L"DXGI_FORMAT_X32_TYPELESS_G8X24_UINT",L"32 ビット型なし成分、および 2 つの符号なし整数成分です (追加の 32 ビットを含む)。")
132- (L"DXGI_FORMAT_R10G10B10A2_TYPELESS",L"4 成分、32 ビット型なしフォーマット")
133- (L"DXGI_FORMAT_R10G10B10A2_UNORM",L"4 成分、32 ビット符号なし整数フォーマット")
134- (L"DXGI_FORMAT_R10G10B10A2_UINT",L"4 成分、32 ビット符号なし整数フォーマット")
135- (L"DXGI_FORMAT_R11G11B10_FLOAT",L"3 成分、32 ビット浮動小数点フォーマット")
136- (L"DXGI_FORMAT_R8G8B8A8_TYPELESS",L"3 成分、32 ビット型なしフォーマット")
137- (L"DXGI_FORMAT_R8G8B8A8_UNORM",L"4 成分、32 ビット符号なし整数フォーマット")
138- (L"DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",L"4 成分、32 ビット符号なし正規化整数 sRGB フォーマット")
139- (L"DXGI_FORMAT_R8G8B8A8_UINT",L"4 成分、32 ビット符号なし整数フォーマット")
140- (L"DXGI_FORMAT_R8G8B8A8_SNORM",L"3 成分、32 ビット符号付き整数フォーマット")
141- (L"DXGI_FORMAT_R8G8B8A8_SINT",L"3 成分、32 ビット符号付き整数フォーマット")
142- (L"DXGI_FORMAT_R16G16_TYPELESS",L"2 成分、32 ビット型なしフォーマット")
143- (L"DXGI_FORMAT_R16G16_FLOAT",L"2 成分、32 ビット浮動小数点フォーマット")
144- (L"DXGI_FORMAT_R16G16_UNORM",L"2 成分、32 ビット符号なし整数フォーマット")
145- (L"DXGI_FORMAT_R16G16_UINT",L"2 成分、32 ビット符号なし整数フォーマット")
146- (L"DXGI_FORMAT_R16G16_SNORM",L"2 成分、32 ビット符号付き整数フォーマット")
147- (L"DXGI_FORMAT_R16G16_SINT",L"2 成分、32 ビット符号付き整数フォーマット")
148- (L"DXGI_FORMAT_R32_TYPELESS",L"1 成分、32 ビット型なしフォーマット")
149- (L"DXGI_FORMAT_D32_FLOAT",L"1 成分、32 ビット浮動小数点フォーマット")
150- (L"DXGI_FORMAT_R32_FLOAT",L"1 成分、32 ビット浮動小数点フォーマット")
151- (L"DXGI_FORMAT_R32_UINT",L"1 成分、32 ビット符号なし整数フォーマット")
152- (L"DXGI_FORMAT_R32_SINT",L"1 成分、32 ビット符号付き整数フォーマット")
153- (L"DXGI_FORMAT_R24G8_TYPELESS",L"2 成分、32 ビット型なしフォーマット")
154- (L"DXGI_FORMAT_D24_UNORM_S8_UINT",L"深度チャンネルに 24 ビット、ステンシル チャンネルに 8 ビットを使用する 32 ビット Z バッファー フォーマット")
155- (L"DXGI_FORMAT_R24_UNORM_X8_TYPELESS",L"1 成分、24 ビット符号なし正規化整数と追加の型なし 8 ビットを含む、32 ビット フォーマット")
156- (L"DXGI_FORMAT_X24_TYPELESS_G8_UINT",L"1 成分、24 ビット型なしフォーマットと追加の 8 ビット符号なし整数成分を含む、32 ビット フォーマット")
157- (L"DXGI_FORMAT_R8G8_TYPELESS",L"2 成分、16 ビット型なしフォーマット")
158- (L"DXGI_FORMAT_R8G8_UNORM",L"2 成分、16 ビット符号なし整数フォーマット")
159- (L"DXGI_FORMAT_R8G8_UINT",L"2 成分、16 ビット符号なし整数フォーマット")
160- (L"DXGI_FORMAT_R8G8_SNORM",L"2 成分、16 ビット符号付き整数フォーマット")
161- (L"DXGI_FORMAT_R8G8_SINT",L"2 成分、16 ビット符号付き整数フォーマット")
162- (L"DXGI_FORMAT_R16_TYPELESS",L"1 成分、16 ビット型なしフォーマット")
163- (L"DXGI_FORMAT_R16_FLOAT",L"1 成分、16 ビット浮動小数点フォーマット")
164- (L"DXGI_FORMAT_D16_UNORM",L"1 成分、16 ビット符号なし正規化整数フォーマット")
165- (L"DXGI_FORMAT_R16_UNORM",L"1 成分、16 ビット符号なし整数フォーマット")
166- (L"DXGI_FORMAT_R16_UINT",L"1 成分、16 ビット符号なし整数フォーマット")
167- (L"DXGI_FORMAT_R16_SNORM",L"1 成分、16 ビット符号付き整数フォーマット")
168- (L"DXGI_FORMAT_R16_SINT",L"1 成分、16 ビット符号付き整数フォーマット")
169- (L"DXGI_FORMAT_R8_TYPELESS",L"1 成分、8 ビット型なしフォーマット")
170- (L"DXGI_FORMAT_R8_UNORM",L"1 成分、8 ビット符号なし整数フォーマット")
171- (L"DXGI_FORMAT_R8_UINT",L"1 成分、8 ビット符号なし整数フォーマット")
172- (L"DXGI_FORMAT_R8_SNORM",L"1 成分、8 ビット符号付き整数フォーマット")
173- (L"DXGI_FORMAT_R8_SINT",L"1 成分、8 ビット符号付き整数フォーマット")
174- (L"DXGI_FORMAT_A8_UNORM",L"1 成分、8 ビット符号なし整数フォーマット")
175- (L"DXGI_FORMAT_R1_UNORM",L"1 成分、1 ビット符号なし正規化整数フォーマット 2.")
176- (L"DXGI_FORMAT_R9G9B9E5_SHAREDEXP",L"4 成分、32 ビット浮動小数点フォーマット 2.")
177- (L"DXGI_FORMAT_R8G8_B8G8_UNORM",L"4 成分、32 ビット符号なし正規化整数フォーマット 3")
178- (L"DXGI_FORMAT_G8R8_G8B8_UNORM",L"4 成分、32 ビット符号なし正規化整数フォーマット 3")
179- (L"DXGI_FORMAT_BC1_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
180- (L"DXGI_FORMAT_BC1_UNORM",L"4 成分、ブロック圧縮フォーマット")
181- (L"DXGI_FORMAT_BC1_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
182- (L"DXGI_FORMAT_BC2_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
183- (L"DXGI_FORMAT_BC2_UNORM",L"4 成分、ブロック圧縮フォーマット")
184- (L"DXGI_FORMAT_BC2_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
185- (L"DXGI_FORMAT_BC3_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
186- (L"DXGI_FORMAT_BC3_UNORM",L"4 成分、ブロック圧縮フォーマット")
187- (L"DXGI_FORMAT_BC3_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
188- (L"DXGI_FORMAT_BC4_TYPELESS",L"1 成分、型なしブロック圧縮フォーマット")
189- (L"DXGI_FORMAT_BC4_UNORM",L"1 成分、ブロック圧縮フォーマット")
190- (L"DXGI_FORMAT_BC4_SNORM",L"1 成分、ブロック圧縮フォーマット")
191- (L"DXGI_FORMAT_BC5_TYPELESS",L"2 成分、型なしブロック圧縮フォーマット")
192- (L"DXGI_FORMAT_BC5_UNORM",L"2 成分、ブロック圧縮フォーマット")
193- (L"DXGI_FORMAT_BC5_SNORM",L"2 成分、ブロック圧縮フォーマット")
194- (L"DXGI_FORMAT_B5G6R5_UNORM",L"3 成分、16 ビット符号なし正規化整数フォーマット")
195- (L"DXGI_FORMAT_B5G5R5A1_UNORM",L"1 ビット アルファをサポートする 4 成分、16 ビット符号なし正規化整数フォーマット")
196- (L"DXGI_FORMAT_B8G8R8A8_UNORM",L"8 ビット アルファをサポートする 4 成分、16 ビット符号なし正規化整数フォーマット")
197- (L"DXGI_FORMAT_B8G8R8X8_UNORM",L"4 成分、16 ビット符号なし正規化整数フォーマット")
198- (L"DXGI_FORMAT_FORCE_UINT",L"コンパイル時に、この列挙型のサイズを 32 ビットにするために定義されています。この値を指定しない場合、一部のコンパイラでは列挙型を 32 ビット以外のサイズでコンパイル可能この定数が使用されることはありません。");
199-
200- // スキャンライン情報
201-
202- std::vector<mode_info> scanline_orders =
203- boost::assign::list_of<mode_info>
204- (L"DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED",L"走査線の順序が指定されていません。")
205- (L"DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE",L"イメージは先頭の走査線~最後の走査線から作成され、スキップされる走査線はありません。")
206- (L"DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST",L"イメージが上部のフィールドから作成されます。")
207- (L"DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST",L"イメージが下部のフィールドから作成されます。");
208-
209- // スケーリングパラメータ
210- std::vector<mode_info> scalings = boost::assign::list_of<mode_info>
211- (L"DXGI_MODE_SCALING_UNSPECIFIED",L"スケーリングが指定されていません。")
212- (L"DXGI_MODE_SCALING_CENTERED",L"スケーリングなしを指定します。イメージはディスプレイの中央に配置されます。通常、このフラグは固定ドットピッチ ディスプレイ (LED ディスプレイなど) に使用します。")
213- (L"DXGI_MODE_SCALING_STRETCHED",L"拡大スケーリングを指定します。");
71+ //HRESULT EnableBlurBehind(HWND hwnd)
72+ //{
73+ // HRESULT hr = S_OK;
74+
75+ // //Create and populate the BlurBehind structre
76+ // DWM_BLURBEHIND bb = {0};
77+ // //Enable Blur Behind and Blur Region;
78+ // bb.dwFlags = DWM_BB_ENABLE;
79+ // bb.fEnable = true;
80+ // bb.hRgnBlur = NULL;
81+
82+ // //Enable Blur Behind
83+ // hr = DwmEnableBlurBehindWindow(hwnd, &bb);
84+ // if (SUCCEEDED(hr))
85+ // {
86+ // //do more things
87+ // }
88+ // return hr;
89+ //}
90+
91+ //// 汎用情報格納用
92+ //struct mode_info
93+ //{
94+ // mode_info(const std::wstring& n,const std::wstring& d) : name(n),description(d) {}
95+ // std::wstring name;
96+ // std::wstring description;
97+ //};
98+
99+ //// ディスプレイモード
100+ //struct display_mode
101+ //{
102+ // display_mode(const std::wstring& n,const std::wstring& d) : name(n),description(d) {}
103+ // std::wstring name;
104+ // std::wstring description;
105+ //};
106+
107+ //std::vector<mode_info> display_modes =
108+ // boost::assign::list_of<mode_info>
109+ // (L"DXGI_FORMAT_UNKNOWN",L"フォーマットが不明")
110+ // (L"DXGI_FORMAT_R32G32B32A32_TYPELESS",L"4 成分、128 ビット型なしフォーマット 1")
111+ // (L"DXGI_FORMAT_R32G32B32A32_FLOAT",L"4 成分、128 ビット浮動小数点フォーマット 1")
112+ // (L"DXGI_FORMAT_R32G32B32A32_UINT",L"4 成分、128 ビット符号なし整数フォーマット 1")
113+ // (L"DXGI_FORMAT_R32G32B32A32_SINT",L"4 成分、128 ビット符号付き整数フォーマット 1")
114+ // (L"DXGI_FORMAT_R32G32B32_TYPELESS",L"3 成分、96 ビット型なしフォーマット")
115+ // (L"DXGI_FORMAT_R32G32B32_FLOAT",L"3 成分、96 ビット浮動小数点フォーマット")
116+ // (L"DXGI_FORMAT_R32G32B32_UINT",L"3 成分、96 ビット符号なし整数フォーマット")
117+ // (L"DXGI_FORMAT_R32G32B32_SINT",L"3 成分、96 ビット符号付き整数フォーマット")
118+ // (L"DXGI_FORMAT_R16G16B16A16_TYPELESS",L"4 成分、64 ビット型なしフォーマット")
119+ // (L"DXGI_FORMAT_R16G16B16A16_FLOAT",L"4 成分、64 ビット浮動小数点フォーマット")
120+ // (L"DXGI_FORMAT_R16G16B16A16_UNORM",L"4 成分、64 ビット符号なし整数フォーマット")
121+ // (L"DXGI_FORMAT_R16G16B16A16_UINT",L"4 成分、64 ビット符号なし整数フォーマット")
122+ // (L"DXGI_FORMAT_R16G16B16A16_SNORM",L"4 成分、64 ビット符号付き整数フォーマット")
123+ // (L"DXGI_FORMAT_R16G16B16A16_SINT",L"4 成分、64 ビット符号付き整数フォーマット")
124+ // (L"DXGI_FORMAT_R32G32_TYPELESS",L"2 成分、64 ビット型なしフォーマット")
125+ // (L"DXGI_FORMAT_R32G32_FLOAT",L"2 成分、64 ビット浮動小数点フォーマット")
126+ // (L"DXGI_FORMAT_R32G32_UINT",L"2 成分、64 ビット符号なし整数フォーマット")
127+ // (L"DXGI_FORMAT_R32G32_SINT",L"2 成分、64 ビット符号付き整数フォーマット")
128+ // (L"DXGI_FORMAT_R32G8X24_TYPELESS",L"2 成分、64 ビット型なしフォーマット")
129+ // (L"DXGI_FORMAT_D32_FLOAT_S8X24_UINT",L"32 ビット浮動小数点成分、および 2 つの符号なし整数成分です (追加の 32 ビットを含む)。")
130+ // (L"DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS",L"32 ビット浮動小数点成分、および 2 つの型なし成分です (追加の 32 ビットを含む)。")
131+ // (L"DXGI_FORMAT_X32_TYPELESS_G8X24_UINT",L"32 ビット型なし成分、および 2 つの符号なし整数成分です (追加の 32 ビットを含む)。")
132+ // (L"DXGI_FORMAT_R10G10B10A2_TYPELESS",L"4 成分、32 ビット型なしフォーマット")
133+ // (L"DXGI_FORMAT_R10G10B10A2_UNORM",L"4 成分、32 ビット符号なし整数フォーマット")
134+ // (L"DXGI_FORMAT_R10G10B10A2_UINT",L"4 成分、32 ビット符号なし整数フォーマット")
135+ // (L"DXGI_FORMAT_R11G11B10_FLOAT",L"3 成分、32 ビット浮動小数点フォーマット")
136+ // (L"DXGI_FORMAT_R8G8B8A8_TYPELESS",L"3 成分、32 ビット型なしフォーマット")
137+ // (L"DXGI_FORMAT_R8G8B8A8_UNORM",L"4 成分、32 ビット符号なし整数フォーマット")
138+ // (L"DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",L"4 成分、32 ビット符号なし正規化整数 sRGB フォーマット")
139+ // (L"DXGI_FORMAT_R8G8B8A8_UINT",L"4 成分、32 ビット符号なし整数フォーマット")
140+ // (L"DXGI_FORMAT_R8G8B8A8_SNORM",L"3 成分、32 ビット符号付き整数フォーマット")
141+ // (L"DXGI_FORMAT_R8G8B8A8_SINT",L"3 成分、32 ビット符号付き整数フォーマット")
142+ // (L"DXGI_FORMAT_R16G16_TYPELESS",L"2 成分、32 ビット型なしフォーマット")
143+ // (L"DXGI_FORMAT_R16G16_FLOAT",L"2 成分、32 ビット浮動小数点フォーマット")
144+ // (L"DXGI_FORMAT_R16G16_UNORM",L"2 成分、32 ビット符号なし整数フォーマット")
145+ // (L"DXGI_FORMAT_R16G16_UINT",L"2 成分、32 ビット符号なし整数フォーマット")
146+ // (L"DXGI_FORMAT_R16G16_SNORM",L"2 成分、32 ビット符号付き整数フォーマット")
147+ // (L"DXGI_FORMAT_R16G16_SINT",L"2 成分、32 ビット符号付き整数フォーマット")
148+ // (L"DXGI_FORMAT_R32_TYPELESS",L"1 成分、32 ビット型なしフォーマット")
149+ // (L"DXGI_FORMAT_D32_FLOAT",L"1 成分、32 ビット浮動小数点フォーマット")
150+ // (L"DXGI_FORMAT_R32_FLOAT",L"1 成分、32 ビット浮動小数点フォーマット")
151+ // (L"DXGI_FORMAT_R32_UINT",L"1 成分、32 ビット符号なし整数フォーマット")
152+ // (L"DXGI_FORMAT_R32_SINT",L"1 成分、32 ビット符号付き整数フォーマット")
153+ // (L"DXGI_FORMAT_R24G8_TYPELESS",L"2 成分、32 ビット型なしフォーマット")
154+ // (L"DXGI_FORMAT_D24_UNORM_S8_UINT",L"深度チャンネルに 24 ビット、ステンシル チャンネルに 8 ビットを使用する 32 ビット Z バッファー フォーマット")
155+ // (L"DXGI_FORMAT_R24_UNORM_X8_TYPELESS",L"1 成分、24 ビット符号なし正規化整数と追加の型なし 8 ビットを含む、32 ビット フォーマット")
156+ // (L"DXGI_FORMAT_X24_TYPELESS_G8_UINT",L"1 成分、24 ビット型なしフォーマットと追加の 8 ビット符号なし整数成分を含む、32 ビット フォーマット")
157+ // (L"DXGI_FORMAT_R8G8_TYPELESS",L"2 成分、16 ビット型なしフォーマット")
158+ // (L"DXGI_FORMAT_R8G8_UNORM",L"2 成分、16 ビット符号なし整数フォーマット")
159+ // (L"DXGI_FORMAT_R8G8_UINT",L"2 成分、16 ビット符号なし整数フォーマット")
160+ // (L"DXGI_FORMAT_R8G8_SNORM",L"2 成分、16 ビット符号付き整数フォーマット")
161+ // (L"DXGI_FORMAT_R8G8_SINT",L"2 成分、16 ビット符号付き整数フォーマット")
162+ // (L"DXGI_FORMAT_R16_TYPELESS",L"1 成分、16 ビット型なしフォーマット")
163+ // (L"DXGI_FORMAT_R16_FLOAT",L"1 成分、16 ビット浮動小数点フォーマット")
164+ // (L"DXGI_FORMAT_D16_UNORM",L"1 成分、16 ビット符号なし正規化整数フォーマット")
165+ // (L"DXGI_FORMAT_R16_UNORM",L"1 成分、16 ビット符号なし整数フォーマット")
166+ // (L"DXGI_FORMAT_R16_UINT",L"1 成分、16 ビット符号なし整数フォーマット")
167+ // (L"DXGI_FORMAT_R16_SNORM",L"1 成分、16 ビット符号付き整数フォーマット")
168+ // (L"DXGI_FORMAT_R16_SINT",L"1 成分、16 ビット符号付き整数フォーマット")
169+ // (L"DXGI_FORMAT_R8_TYPELESS",L"1 成分、8 ビット型なしフォーマット")
170+ // (L"DXGI_FORMAT_R8_UNORM",L"1 成分、8 ビット符号なし整数フォーマット")
171+ // (L"DXGI_FORMAT_R8_UINT",L"1 成分、8 ビット符号なし整数フォーマット")
172+ // (L"DXGI_FORMAT_R8_SNORM",L"1 成分、8 ビット符号付き整数フォーマット")
173+ // (L"DXGI_FORMAT_R8_SINT",L"1 成分、8 ビット符号付き整数フォーマット")
174+ // (L"DXGI_FORMAT_A8_UNORM",L"1 成分、8 ビット符号なし整数フォーマット")
175+ // (L"DXGI_FORMAT_R1_UNORM",L"1 成分、1 ビット符号なし正規化整数フォーマット 2.")
176+ // (L"DXGI_FORMAT_R9G9B9E5_SHAREDEXP",L"4 成分、32 ビット浮動小数点フォーマット 2.")
177+ // (L"DXGI_FORMAT_R8G8_B8G8_UNORM",L"4 成分、32 ビット符号なし正規化整数フォーマット 3")
178+ // (L"DXGI_FORMAT_G8R8_G8B8_UNORM",L"4 成分、32 ビット符号なし正規化整数フォーマット 3")
179+ // (L"DXGI_FORMAT_BC1_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
180+ // (L"DXGI_FORMAT_BC1_UNORM",L"4 成分、ブロック圧縮フォーマット")
181+ // (L"DXGI_FORMAT_BC1_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
182+ // (L"DXGI_FORMAT_BC2_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
183+ // (L"DXGI_FORMAT_BC2_UNORM",L"4 成分、ブロック圧縮フォーマット")
184+ // (L"DXGI_FORMAT_BC2_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
185+ // (L"DXGI_FORMAT_BC3_TYPELESS",L"4 成分、型なしブロック圧縮フォーマット")
186+ // (L"DXGI_FORMAT_BC3_UNORM",L"4 成分、ブロック圧縮フォーマット")
187+ // (L"DXGI_FORMAT_BC3_UNORM_SRGB",L"sRGB データ用の 4 成分、ブロック圧縮フォーマット")
188+ // (L"DXGI_FORMAT_BC4_TYPELESS",L"1 成分、型なしブロック圧縮フォーマット")
189+ // (L"DXGI_FORMAT_BC4_UNORM",L"1 成分、ブロック圧縮フォーマット")
190+ // (L"DXGI_FORMAT_BC4_SNORM",L"1 成分、ブロック圧縮フォーマット")
191+ // (L"DXGI_FORMAT_BC5_TYPELESS",L"2 成分、型なしブロック圧縮フォーマット")
192+ // (L"DXGI_FORMAT_BC5_UNORM",L"2 成分、ブロック圧縮フォーマット")
193+ // (L"DXGI_FORMAT_BC5_SNORM",L"2 成分、ブロック圧縮フォーマット")
194+ // (L"DXGI_FORMAT_B5G6R5_UNORM",L"3 成分、16 ビット符号なし正規化整数フォーマット")
195+ // (L"DXGI_FORMAT_B5G5R5A1_UNORM",L"1 ビット アルファをサポートする 4 成分、16 ビット符号なし正規化整数フォーマット")
196+ // (L"DXGI_FORMAT_B8G8R8A8_UNORM",L"8 ビット アルファをサポートする 4 成分、16 ビット符号なし正規化整数フォーマット")
197+ // (L"DXGI_FORMAT_B8G8R8X8_UNORM",L"4 成分、16 ビット符号なし正規化整数フォーマット")
198+ // (L"DXGI_FORMAT_FORCE_UINT",L"コンパイル時に、この列挙型のサイズを 32 ビットにするために定義されています。この値を指定しない場合、一部のコンパイラでは列挙型を 32 ビット以外のサイズでコンパイル可能この定数が使用されることはありません。");
199+
200+ //// スキャンライン情報
201+
202+ //std::vector<mode_info> scanline_orders =
203+ // boost::assign::list_of<mode_info>
204+ // (L"DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED",L"走査線の順序が指定されていません。")
205+ // (L"DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE",L"イメージは先頭の走査線~最後の走査線から作成され、スキップされる走査線はありません。")
206+ // (L"DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST",L"イメージが上部のフィールドから作成されます。")
207+ // (L"DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST",L"イメージが下部のフィールドから作成されます。");
208+
209+ //// スケーリングパラメータ
210+ //std::vector<mode_info> scalings = boost::assign::list_of<mode_info>
211+ // (L"DXGI_MODE_SCALING_UNSPECIFIED",L"スケーリングが指定されていません。")
212+ // (L"DXGI_MODE_SCALING_CENTERED",L"スケーリングなしを指定します。イメージはディスプレイの中央に配置されます。通常、このフラグは固定ドットピッチ ディスプレイ (LED ディスプレイなど) に使用します。")
213+ // (L"DXGI_MODE_SCALING_STRETCHED",L"拡大スケーリングを指定します。");
214214
215215 struct simple_vertex
216216 {
@@ -1019,13 +1019,13 @@ namespace sf
10191019
10201020 THROW_IFERR(wic_factory->CreateBitmapScaler(&scaler));
10211021 THROW_IFERR(scaler->Initialize(
1022- decoder_source,
1022+ decoder_source.Get(),
10231023 destination_width,
10241024 destination_height,
10251025 WICBitmapInterpolationModeCubic
10261026 ));
10271027 THROW_IFERR(converter->Initialize(
1028- scaler.GetInterfacePtr(),
1028+ scaler.Get(),
10291029 GUID_WICPixelFormat32bppPBGRA,
10301030 WICBitmapDitherTypeNone,
10311031 NULL,
@@ -1036,7 +1036,7 @@ namespace sf
10361036 else // Don't scale the image.
10371037 {
10381038 THROW_IFERR(converter->Initialize(
1039- decoder_source.GetInterfacePtr(),
1039+ decoder_source.Get(),
10401040 GUID_WICPixelFormat32bppPBGRA,
10411041 WICBitmapDitherTypeNone,
10421042 NULL,
@@ -1047,9 +1047,9 @@ namespace sf
10471047
10481048 // Create a Direct2D bitmap from the WIC bitmap.
10491049 THROW_IFERR(render_target->CreateBitmapFromWicBitmap(
1050- converter.GetInterfacePtr(),
1050+ converter.Get(),
10511051 NULL,
1052- &bitmap
1052+ bitmap.GetAddressOf()
10531053 ));
10541054
10551055 return bitmap;
--- a/wasapi2/wasapi.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
1-/*
2- ==============================================================================
3-
4- Copyright 2005-11 by Satoshi Fujiwara.
5-
6- async can be redistributed and/or modified under the terms of the
7- GNU General Public License, as published by the Free Software Foundation;
8- either version 2 of the License, or (at your option) any later version.
9-
10- async is distributed in the hope that it will be useful,
11- but WITHOUT ANY WARRANTY; without even the implied warranty of
12- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13- GNU General Public License for more details.
14-
15- You should have received a copy of the GNU General Public License
16- along with async; if not, visit www.gnu.org/licenses or write to the
17- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18- Boston, MA 02111-1307 USA
19-
20- ==============================================================================
21-*/
22-
23-#include "StdAfx.h"
24-#if _DEBUG
25-#define _CRTDBG_MAP_ALLOC
26-#include <crtdbg.h>
27-#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
28-#endif
29-#include "sf_memory.h"
30-#include "audio_base.h"
31-#include "wasapi.h"
32-
33-using namespace std;
34-
35-namespace sf{
36-
37-
38- wasapi_shared_timer::wasapi_shared_timer()
39- : is_enabled_(false),position_(0),is_start_(false)
40- {
41-// co_task_memory<WAVEFORMATEX> wfx;
42- get_default_audio_client();
43- WAVEFORMATEXTENSIBLE w;
44- wasapi_device_manager::device_info::current_device_params& params(wasapi_device_manager::instance()->current_input_device().current_params);
45- bits_pair bits = {params.bits,params.valid_bits};
46- make_wave_format(w,params.sample_rate,params.channel,bits);
47- latency_ = wasapi_device_manager::instance()->current_output_device().latency_default;
48-// audio_client_->GetMixFormat(&wfx);
49- //WAVEFORMATEXTENSIBLE* w(reinterpret_cast<WAVEFORMATEXTENSIBLE*>(wfx.get()));
50- //w->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
51- //w->Format.wBitsPerSample = 16;
52- //w->Format.nBlockAlign = (w->Format.wBitsPerSample / 8) * w->Format.nChannels;
53- //w->Format.nAvgBytesPerSec = w->Format.nSamplesPerSec *w->Format.nBlockAlign;
54- //w->Samples.wValidBitsPerSample = 16;
55- init(w);
56- }
57-
58- wasapi_shared_timer::wasapi_shared_timer(int device_index,wasapi_device_manager::device_info::current_device_params& params)
59- : is_enabled_(false),position_(0),is_start_(false)
60- {
61- current_device_ = wasapi_device_manager::instance()->output_device_infos().at(device_index).device_ptr;
62- // オーディオクライアントを取得
63- THROW_IF_ERR(
64- current_device_
65- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
66- NULL, reinterpret_cast<void **>(&audio_client_))
67- );
68- WAVEFORMATEXTENSIBLE w;
69- bits_pair bits = {params.bits,params.valid_bits};
70- make_wave_format(w,params.sample_rate,params.channel,bits);
71- latency_ = params.latency;//wasapi_device_manager::instance()->current_output_device().latency_default;
72- init(w);
73- }
74-
75-
76- void wasapi_shared_timer::get_default_audio_client()
77- {
78- // IMMDeviceEnumeratorの取得
79- //THROW_IF_ERR(
80- // CoCreateInstance(
81- // __uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
82- // IID_PPV_ARGS(&device_enumerator_)));
83-
84- // デフォルトのオーディオデバイスを取得する
85- //THROW_IF_ERR(
86- // device_enumerator_
87- // ->GetDefaultAudioEndpoint(eRender,eMultimedia,&current_device_)
88- // );
89-
90- current_device_ = wasapi_device_manager::instance()->current_output_device().device_ptr;
91-
92- // オーディオクライアントを取得
93- THROW_IF_ERR(
94- current_device_
95- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
96- NULL, reinterpret_cast<void **>(&audio_client_))
97- );
98- }
99-
100- void wasapi_shared_timer::init(::WAVEFORMATEXTENSIBLE& wfx)
101- {
102- // 代替フォーマット定義
103- sf::co_task_memory<WAVEFORMATEX> alt_format;
104-
105- // 読みこもうとしているWAVファイルのフォーマットをサポートしているか?
106- HRESULT hr = audio_client_->IsFormatSupported(
107- AUDCLNT_SHAREMODE_SHARED ,&wfx.Format,&alt_format);
108-// bool sample_rate_convert = false;
109- float sample_rate_backup = 0.0f;
110- if(hr != S_OK) // S_FALSEならそのフォーマットをサポートしていないらしい..
111- {
112- // サンプルレートのコンバート
113- if(alt_format->nSamplesPerSec != wfx.Format.nSamplesPerSec)
114- {
115- // 本来のサンプルレートをバックアップする
116- sample_rate_backup = wfx.Format.nSamplesPerSec;
117- // 代替フォーマットのサンプルレートをセットする
118- wfx.Format.nSamplesPerSec = alt_format->nSamplesPerSec;
119- // 再計算する
120- wfx.Format.nAvgBytesPerSec = alt_format->nSamplesPerSec * wfx.Format.nBlockAlign;
121- // もう一回チェックする。
122- // サンプルレート以外でサポートしていない点があれば例外が発生する。
123- THROW_IF_ERR(audio_client_->IsFormatSupported(
124- AUDCLNT_SHAREMODE_SHARED ,&wfx.Format,&alt_format));
125- // フラグをセットする
126-// sample_rate_convert = true;
127- } else {
128- // サンプルレート以外であれば例外を出す。
129- throw win32_error_exception(hr);
130- }
131- }
132-
133- // 再生クライアントの初期化
134-
135- REFERENCE_TIME buffer_period = latency_;
136-
137- REFERENCE_TIME buffer_duration = buffer_period * periods_per_buffer_;
138-
139- THROW_IF_ERR(audio_client_->Initialize(AUDCLNT_SHAREMODE_SHARED ,
140- AUDCLNT_STREAMFLAGS_NOPERSIST /*| AUDCLNT_STREAMFLAGS_RATEADJUST*/,
141- buffer_duration,
142- 0/*buffer_period*/,
143- &(wfx.Format),
144- NULL));
145-
146- // バッファサイズの取得
147- THROW_IF_ERR(audio_client_->GetBufferSize(&buffer_size_));
148-
149- // 再生クライアントの取得
150- THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&audio_render_client_)));
151-
152- REFERENCE_TIME psl;
153- THROW_IF_ERR(audio_client_->GetStreamLatency(&psl));
154-#ifdef _DEBUG
155- wdout << L"StreamLatency:" << psl << endl;
156-#endif
157-// wdout
158-
159- // サンプルレートコンバータ
160- //if(sample_rate_convert)
161- //{
162- // THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&audio_clock_adjustment_)));
163- // // 本来のサンプルレートをセットする
164- // audio_clock_adjustment_->SetSampleRate(sample_rate_backup);
165- //}
166-
167- num_of_frames_ = wfx.Format.nBlockAlign;
168- mix_format_ = wfx;
169- //inc_ = (buffer_size_ * num_of_frames_) / (sizeof(short) * periods_per_buffer_);
170- buffer_in_periods_ = buffer_size_ / periods_per_buffer_;
171-
172- is_enabled_ = true;
173- }
174-
175- wasapi_shared_timer::wasapi_shared_timer(::WAVEFORMATEXTENSIBLE& wfx)
176- : is_enabled_(false),position_(0),is_start_(false)
177- {
178-
179- try {
180- // thread_priority_.set_priority(AVRT_PRIORITY_NORMAL);
181-
182- // WASAPIの初期化処理
183-
184- get_default_audio_client();
185-
186- init(wfx);
187-
188- } catch (win32_error_exception& e)
189- {
190- exception_holder_.reset(new win32_error_exception(e.hresult()));
191- is_enabled_ = false;
192- } catch(...) {
193- is_enabled_ = false;
194- }
195- }
196-
197- wasapi_shared_timer::~wasapi_shared_timer()
198- {
199-// safe_release(audio_clock_adjustment_);
200-
201- // WASAPIの終了処理
202- if(audio_client_)
203- {
204- audio_client_->Stop();
205- audio_client_->Reset();
206- safe_release(audio_render_client_);
207- audio_client_.Release();
208- }
209-
210- safe_release(current_device_);
211-// safe_release(device_enumerator_);
212- }
213-
214- void wasapi_shared_timer::create_wave_data(){
215- // サイン波の生成
216- boost::uint32_t buffer_size_in_bytes = buffer_size_ * mix_format_.Format.nBlockAlign;
217- size_t render_data_length = mix_format_.Format.nSamplesPerSec * 10 /* 秒 */ * mix_format_.Format.nBlockAlign / sizeof(short);
218- tone_buffer_.reserve(render_data_length);
219-
220- double sampleIncrement = (440 /* Hz */ * (M_PI * 2.0)) / (double)mix_format_.Format.nSamplesPerSec;
221- double theta = 0.0;
222-
223- for (size_t i = 0 ; i < render_data_length ; i += mix_format_.Format.nChannels)
224- {
225- double sinValue = sin( theta );
226- for(size_t j = 0 ;j < mix_format_.Format.nChannels; j++)
227- {
228- tone_buffer_.push_back((short)(sinValue * _I16_MAX));
229- }
230- theta += sampleIncrement;
231- }
232- };
233-
234- void wasapi_shared_timer::play_buffer(BYTE* source_buffer)
235- {
236- BYTE* buffer;
237-
238- if(!is_start_)
239- {
240-
241- // 最初にバッファを埋める
242- THROW_IF_ERR(audio_render_client_->GetBuffer(buffer_size_,&buffer));
243- ::CopyMemory(buffer,source_buffer,get_buffer_byte_size());
244-
245- // レイテンシ時間*バッファ数分進める
246- THROW_IF_ERR(audio_render_client_->ReleaseBuffer(buffer_size_,0));
247-
248- // 再生開始
249- THROW_IF_ERR(audio_client_->Start());
250- is_start_ = true;
251- return;
252- }
253-
254-
255- // レイテンシ時間だけ待つ
256- Sleep(latency_ / 10000);
257-
258- uint32_t padding;
259- uint32_t frames_available;
260- uint32_t count_period = periods_per_buffer_;
261- while(count_period > 0)
262- {
263- // パディングを求める。
264- THROW_IF_ERR(audio_client_->GetCurrentPadding(&padding));
265- frames_available = buffer_size_ - padding;
266-
267- // パディングを除いた部分のバッファを埋める。
268- // パディングを除いた部分のサイズがbuffer_in_periods_より小さい場合はつぎにまわす。
269- // パディングを除いた部分を一気に埋めようとしたけどできなかった。。
270- while(buffer_in_periods_ <= frames_available && count_period > 0 )
271- {
272- THROW_IF_ERR(audio_render_client_->GetBuffer(buffer_in_periods_,&buffer));
273- ::CopyMemory(buffer,source_buffer,buffer_in_periods_ * num_of_frames_);
274- THROW_IF_ERR(audio_render_client_->ReleaseBuffer(buffer_in_periods_,0));
275- // レイテンシ時間だけ進める
276- source_buffer += buffer_in_periods_ * num_of_frames_;
277- --count_period;
278- // パディングを再度求める
279- THROW_IF_ERR(audio_client_->GetCurrentPadding(&padding));
280- frames_available = buffer_size_ - padding;
281- }
282-
283- if(count_period > 0)
284- {
285- Sleep(latency_ / 10000);
286- }
287- }
288- }
289- void wasapi_shared_timer::reset()
290- {
291- THROW_IF_ERR(audio_client_->Reset());
292- }
293- void wasapi_shared_timer::stop() {
294- //再生停止
295- if(is_start_)
296- {
297- THROW_IF_ERR(audio_client_->Stop());
298- reset();
299- is_start_ = false;
300-
301- };
302- }
303-}
--- a/wasapi2/wasapi.h
+++ b/wasapi2/wasapi.h
@@ -34,283 +34,465 @@ Boston, MA 02111-1307 USA
3434 #define _USE_MATH_DEFINES
3535 #include <math.h>
3636 #include <limits.h>
37-#pragma comment(lib, "winmm.lib")
38-#pragma comment(lib, "Avrt.lib")
3937
4038 #include "audio_base.h"
41-#include "audio_source.h"
42-#include "Functiondiscoverykeys_devpkey.h"
43-
44-// COM Pointer 定義
45-_COM_SMARTPTR_TYPEDEF(IMMDeviceEnumerator,__uuidof(IMMDeviceEnumerator));
46-_COM_SMARTPTR_TYPEDEF(IMMDevice,__uuidof(IMMDevice));
47-_COM_SMARTPTR_TYPEDEF(IMMDeviceCollection,__uuidof(IMMDeviceCollection));
48-_COM_SMARTPTR_TYPEDEF(IPropertyStore,__uuidof(IPropertyStore));
49-
50-_COM_SMARTPTR_TYPEDEF(IAudioClient,__uuidof(IAudioClient));
51-_COM_SMARTPTR_TYPEDEF(IAudioClock,__uuidof(IAudioClock));
52-_COM_SMARTPTR_TYPEDEF(IAudioClock2,__uuidof(IAudioClock2));
53-_COM_SMARTPTR_TYPEDEF(IAudioRenderClient,__uuidof(IAudioRenderClient));
54-_COM_SMARTPTR_TYPEDEF(IAudioCaptureClient,__uuidof(IAudioCaptureClient));
55-_COM_SMARTPTR_TYPEDEF(IAudioClockAdjustment,__uuidof(IAudioClockAdjustment));
39+//#include "audio_source.h"
40+//#include "Functiondiscoverykeys_devpkey.h"
5641
57-namespace sf {
58- namespace mpl = boost::mpl;
59- struct bits_pair
60- {
61- int bits_per_sample;
62- int valid_bits_per_sample;
63- };
64-
65- void make_wave_format(WAVEFORMATEXTENSIBLE& format,
66- int sample_rate,int channels,bits_pair bits,
67- uint32_t type = WAVE_FORMAT_EXTENSIBLE,
68- const GUID& sub_type = KSDATAFORMAT_SUBTYPE_PCM);
69-
70- void make_wave_format
71- (WAVEFORMATEX& format,int sample_rate,int channels,
72- int bits,uint32_t type = WAVE_FORMAT_PCM);
73-
74-
75- struct wasapi_device_manager : singleton<wasapi_device_manager>
76- {
77- static const int NUM_SAMPLE_RATE = 12;
78- static const int NUM_SAMPLE_BITS = 6;
79- static const int sample_rates[NUM_SAMPLE_RATE];
80-
81-
82- static const bits_pair sample_bits[NUM_SAMPLE_BITS];
83-
84- typedef std::map<int,std::map<int,std::map<int,std::map<int,std::map<int,int> > > > > format_map_type;
85-
86- struct device_info
87- {
88-
89- device_info(std::wstring& i,std::wstring& difn,std::wstring& dd,std::wstring& dfn,IMMDevicePtr p);
90- ~device_info();
91- std::wstring id;
92- std::wstring device_interface_friendly_name;
93- std::wstring device_description;
94- std::wstring device_friendly_name;
95- bool is_selected;
96- IMMDevicePtr device_ptr;
97- format_map_type support_formats;
98- REFERENCE_TIME latency_minimum;
99- REFERENCE_TIME latency_default;
100- struct params_t
101- {
102- params_t()
103- : exclusive_mode(false),event_mode(false),bits(16),valid_bits(16),sample_rate(44100),latency(0),channel(2)
104- {}
105- bool exclusive_mode;
106- bool event_mode;
107- int bits;
108- int valid_bits;
109- int sample_rate;
110- REFERENCE_TIME latency;
111- int channel;
112- private:
113- friend class boost::serialization::access;
114- template<class Archive>
115- void serialize(Archive& ar, const unsigned int version)
116- {
117- ar & BOOST_SERIALIZATION_NVP(exclusive_mode);
118- ar & BOOST_SERIALIZATION_NVP(event_mode);
119- ar & BOOST_SERIALIZATION_NVP(bits);
120- ar & BOOST_SERIALIZATION_NVP(valid_bits);
121- ar & BOOST_SERIALIZATION_NVP(sample_rate);
122- ar & BOOST_SERIALIZATION_NVP(latency);
123- ar & BOOST_SERIALIZATION_NVP(channel);
124- }
125- };
126- params_t params;
127- };
128-
129- typedef std::vector<device_info> device_infos_t;
130-
131- wasapi_device_manager();
132- ~wasapi_device_manager();
133-
134- device_info& current_output_device(){return output_device_infos_[output_device_index_];};
135- device_info& current_input_device() {return input_device_infos_[input_device_index_];};
136-
137- device_infos_t& output_device_infos() {return output_device_infos_;}
138- device_infos_t& input_device_infos() {return input_device_infos_;}
139-
140- void select_output_device(int index) { assert(index < output_device_infos_.size()) ; output_device_index_ = index;}
141- void select_input_device(int index) { assert(index < input_device_infos_.size()) ; input_device_index_ = index;}
142- int current_output_device_index() const {return output_device_index_;}
143- int current_input_device_index() const {return input_device_index_;}
144- private:
145- int get_device_infos(EDataFlow data_flow, std::vector<device_info>& infos,const std::wstring& idd);
146- IMMDeviceEnumeratorPtr device_enumerator_;
147- int output_device_index_;
148- int input_device_index_;
149- std::vector<device_info> output_device_infos_;
150- std::vector<device_info> input_device_infos_;
151- };
152-
153- // タイマーモードのポリシークラス
154- struct wasapi_timer_policy
155- {
156- wasapi_timer_policy(REFERENCE_TIME & latency) : latency_(latency) {};
157- void wait(){ Sleep(latency_ / 20000L);}
158- static const int STREAM_FLAG = 0;
159- private:
160- const REFERENCE_TIME& latency_;
161- };
162-
163- // イベントモードのポリシークラス
164- struct wasapi_event_policy
165- {
166- wasapi_event_policy() :
167- wait_events_(::CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE)) {}
168-
169- void wait()
170- {
171- WaitForSingleObject(wait_events_.get(),INFINITE);
172- ;
173- }
174-
175- HANDLE event_handle(){return wait_events_.get();}
176- static const int STREAM_FLAG = AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
177- private:
178- handle_holder wait_events_;
179- };
180-
181- // 排他モードのポリシークラス
182- struct wasapi_exclusive_policy
183- {
184- static const AUDCLNT_SHAREMODE SHARE_MODE = AUDCLNT_SHAREMODE_EXCLUSIVE;
185- };
186-
187- // 共有モードのポリシークラス
188- struct wasapi_shared_policy
189- {
190- static const AUDCLNT_SHAREMODE SHARE_MODE = AUDCLNT_SHAREMODE_SHARED;
191- };
192-
193- // レンダークライアントのポリシークラス
194- struct render_client_policy
195- {
196- //typedef IAudioRenderClientPtr client_ptr_t;
197- };
198-
199- // キャプチャのポリシークラス
200- struct capture_client_policy
201- {
202- //typedef IAudioCaptureClientPtr client_ptr_t;
203- };
204-
205- // キャプチャのポリシークラス
206- struct loopback_capture_client_policy
207- {
208- //typedef IAudioCaptureClientPtr client_ptr_t;
209- };
210-
211- /// WASAPI処理クラス(デフォルト:共有・タイマーモード)
212- template <typename ShareModePolicy = wasapi_shared_policy,typename DrivenPolicy = wasapi_timer_policy,typename IOClientPolicy = render_client_policy>
213- struct wasapi_base : public audio_base
214- {
215- friend IOClientPolicy;
216- //typedef typename IOClientPolicy::client_ptr_t client_ptr_t;
217- typedef wasapi_base<ShareModePolicy,DrivenPolicy> this_type;
218- //wasapi_base();
219- wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params);
220- //explicit wasapi_base(::WAVEFORMATEXTENSIBLE& wfx);
221- virtual ~wasapi_base();
222-
223- bool is_enabled () const {return is_enabled_;}
224-
225- /// テスト用 サイン波データの生成
226- void create_wave_data();
227-
228- /// サウンド再生処理
229- // bool play_buffer(BYTE* buffer);
230- bool is_start(){ return is_start_; }
231- // 出力用
232- uint32_t get_buffer(BYTE** buffer,uint32_t size);
233- // キャプチャ用
234- uint32_t get_buffer(BYTE** buffer);
235-
236- void release_buffer(uint32_t num_byte_written);
237-
238- void start();
239- void stop();
240- void reset();
241- void wait(){driven_policy_.wait();};
242- uint32_t get_current_padding();
243- uint64_t get_position() const
244- {
245- uint64_t pos = 0;
246- audio_clock2_->GetPosition(&pos,0);
247- return pos;
248- };
249- uint32_t get_buffer_byte_size () const { return buffer_size_ * num_of_frames_;}
250- uint32_t get_frame_size() const {return num_of_frames_;}
251- uint32_t get_buffer_size () const { return buffer_size_; }
252- uint64_t get_buffer_duration() { return latency_;}
253- uint32_t get_channel() { return mix_format_.Format.nChannels; }
254- win32_error_exception* const result() {return exception_holder_.get(); }
255-
256- private:
257-
258- void init_io_client( boost::type<render_client_policy>)
259- {
260- // 再生クライアントの取得
261- THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&render_client_)));
262- };
263-
264- void init_io_client(boost::type<capture_client_policy>)
265- {
266- // 再生クライアントの取得
267- THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&capture_client_)));
268- };
269-
270- void init_audio_client(WAVEFORMATEXTENSIBLE& wfx);
271- DrivenPolicy driven_policy_;
272- void get_default_audio_client();
273- void init(IMMDevicePtr device,wasapi_device_manager::device_info::params_t& params);
274- // IMMDeviceEnumeratorPtr device_enumerator_;
275- IMMDevicePtr current_device_;
276- IAudioClientPtr audio_client_;
277- IAudioRenderClientPtr render_client_;
278- IAudioCaptureClientPtr capture_client_;
279- IAudioClockPtr audio_clock2_;
280- //IAudioClockAdjustmentPtr audio_clock_adjustment_;
281- //handle_holder buffer_control_event_;
282- WAVEFORMATEXTENSIBLE mix_format_;
283- bool is_enabled_;
284- bool is_start_;
285- boost::shared_ptr<win32_error_exception> exception_holder_;
286- boost::uint32_t num_of_frames_;
287- boost::uint32_t buffer_size_;
288- uint64_t position_;
289- std::vector<short> tone_buffer_;
290- size_t buffer_in_periods_;// = buffer_size_ / periods_per_buffer_;
291-
292- // バッファ中の区切り数(レイテンシ時間が何個あるか)
293- static const uint32_t periods_per_buffer_ = 1;
294- //= mpl::if_c<boost::is_same<this_type,wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy> >::value,
295- // mpl::int_<1>,mpl::int_<1> >::type::value;
296-
297- // 再生レイテンシ
298- REFERENCE_TIME latency_;/* ms */
299- REFERENCE_TIME actual_latency_;
300- };
301-
302- typedef wasapi_base<wasapi_shared_policy,wasapi_timer_policy> wasapi_shared_timer;
303- typedef wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy> wasapi_exclusive_timer;
304-
305- typedef wasapi_base<wasapi_shared_policy,wasapi_event_policy> wasapi_shared_event;
306- typedef wasapi_base<wasapi_exclusive_policy,wasapi_event_policy> wasapi_exclusive_event;
307-
308- typedef wasapi_base<wasapi_shared_policy,wasapi_timer_policy,capture_client_policy> wasapi_capture_shared_timer;
309- typedef wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy,capture_client_policy> wasapi_capture_exclusive_timer;
310-
311- typedef wasapi_base<wasapi_shared_policy,wasapi_event_policy,capture_client_policy> wasapi_capture_shared_event;
312- typedef wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy> wasapi_capture_exclusive_event;
42+// COM Smart Pointer 定義
43+
44+//typedef Microsoft::WRL::ComPtr<IPropertyStore> IPropertyStorePtr;
45+typedef Microsoft::WRL::ComPtr<IAudioClient> IAudioClientPtr;
46+typedef Microsoft::WRL::ComPtr<IAudioClient2> IAudioClient2Ptr;
47+typedef Microsoft::WRL::ComPtr<IAudioClock> IAudioClockPtr;
48+typedef Microsoft::WRL::ComPtr<IAudioClock2> IAudioClock2Ptr;
49+typedef Microsoft::WRL::ComPtr<IAudioRenderClient> IAudioRenderClientPtr;
50+typedef Microsoft::WRL::ComPtr<IAudioCaptureClient> IAudioCaptureClientPtr;
51+typedef Microsoft::WRL::ComPtr<IAudioClockAdjustment> IAudioClockAdjustmentPtr;
31352
53+namespace sf {
54+ namespace mpl = boost::mpl;
55+
56+ template <typename TSender,typename TResult>
57+ ref class typed_event_handler_adapter
58+ {
59+ internal:
60+ typedef std::function<void (TSender,TResult)> wrapped_method_type;
61+ typed_event_handler_adapter(wrapped_method_type wrapped_method)
62+ : wrapped_method_(wrapped_method)
63+ {
64+ proxy_handler_ =
65+ ref new Windows::Foundation::TypedEventHandler<TSender, TResult>
66+ (this,&typed_event_handler_adapter::proxy_handler);
67+ }
68+
69+ void proxy_handler(TSender sender,TResult result)
70+ {
71+ wrapped_method_(sender,result);
72+ }
73+
74+ Windows::Foundation::TypedEventHandler<TSender, TResult>^ get()
75+ {
76+ return proxy_handler_;
77+ }
78+ private:
79+ wrapped_method_type wrapped_method_;
80+ Windows::Foundation::TypedEventHandler<TSender, TResult>^ proxy_handler_;
81+ };
82+
83+ namespace en = Windows::Devices::Enumeration;
84+ namespace f = Windows::Foundation;
85+
86+ ref class DeviceWatcherAdapter
87+ {
88+ internal:
89+ DeviceWatcherAdapter(en::DeviceClass deviceClass = en::DeviceClass::AudioRender)
90+ {
91+ watcher_ = en::DeviceInformation::CreateWatcher(deviceClass);
92+ watcher_->Added += ref new f::TypedEventHandler<en::DeviceWatcher^,en::DeviceInformation^>(this,&DeviceWatcherAdapter::Added);
93+ watcher_->EnumerationCompleted += ref new f::TypedEventHandler<en::DeviceWatcher^ , Platform::Object^ >(this,&DeviceWatcherAdapter::EnumerationCompleted);
94+ watcher_->Updated += ref new f::TypedEventHandler<en::DeviceWatcher^ , en::DeviceInformationUpdate^ >(this,&DeviceWatcherAdapter::Updated);
95+ watcher_->Removed += ref new f::TypedEventHandler<en::DeviceWatcher^ , en::DeviceInformationUpdate^ >(this,&DeviceWatcherAdapter::Removed);
96+ watcher_->Stopped += ref new f::TypedEventHandler<en::DeviceWatcher^ , Platform::Object^ >(this,&DeviceWatcherAdapter::Stopped);
97+ }
98+
99+ boost::signals2::signal<void (en::DeviceWatcher^ sender
100+ , en::DeviceInformation^ deviceInterface) >& added(){return added_;}
101+ boost::signals2::signal<void (en::DeviceWatcher^ sender,
102+ Platform::Object^ obj) > &enumration_completed(){return enumration_completed_;}
103+ boost::signals2::signal<void (en::DeviceWatcher^ sender,
104+ en::DeviceInformationUpdate^ deviceInfo) >& updated(){return updated_;}
105+ boost::signals2::signal<void (en::DeviceWatcher^ sender,
106+ en::DeviceInformationUpdate^ deviceInfo) >& removed() { return removed_;}
107+ boost::signals2::signal<void (en::DeviceWatcher^ sender,
108+ Platform::Object^ obj) >& stopped() {return stopped_;}
109+ void start()
110+ {
111+ watcher_->Start();
112+ }
113+ void stop()
114+ {
115+ watcher_->Stop();
116+ }
117+ private:
118+ void Added(en::DeviceWatcher^ sender, en::DeviceInformation^ deviceInterface)
119+ {
120+ if(!added_.empty()){
121+ added_(sender,deviceInterface);
122+ }
123+ }
124+ void EnumerationCompleted(en::DeviceWatcher^ sender, Platform::Object^ obj)
125+ {
126+ if(!enumration_completed_.empty()){
127+ enumration_completed_(sender,obj);
128+ }
129+ }
130+ void Updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)
131+ {
132+ if(!updated_.empty()){
133+ updated_(sender,deviceInfo);
134+ }
135+ }
136+ void Removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)
137+ {
138+ if(!removed_.empty()){
139+ removed_(sender,deviceInfo);
140+ }
141+ }
142+ void Stopped(en::DeviceWatcher^ sender, Platform::Object^ obj)
143+ {
144+ if(!stopped_.empty()){
145+ stopped_(sender,obj);
146+ }
147+ }
148+ en::DeviceWatcher^ watcher_;
149+ boost::signals2::signal<void (en::DeviceWatcher^ sender
150+ , en::DeviceInformation^ deviceInterface) > added_;
151+ boost::signals2::signal<void (en::DeviceWatcher^ sender, Platform::Object^ obj) > enumration_completed_;
152+ boost::signals2::signal<void (en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo) > updated_;
153+ boost::signals2::signal<void (en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo) > removed_;
154+ boost::signals2::signal<void (en::DeviceWatcher^ sender, Platform::Object^ obj) > stopped_;
155+ };
156+
157+ struct bits_pair
158+ {
159+ int bits_per_sample;
160+ int valid_bits_per_sample;
161+ };
162+
163+ void make_wave_format(WAVEFORMATEXTENSIBLE& format,
164+ int sample_rate,int channels,bits_pair bits,
165+ uint32_t type = WAVE_FORMAT_EXTENSIBLE,
166+ const GUID& sub_type = KSDATAFORMAT_SUBTYPE_PCM);
167+
168+ void make_wave_format
169+ (WAVEFORMATEX& format,int sample_rate,int channels,
170+ int bits,uint32_t type = WAVE_FORMAT_PCM);
171+
172+
173+ struct wasapi_device_manager : singleton<wasapi_device_manager>
174+ {
175+ static const int NUM_SAMPLE_RATE = 12;
176+ static const int NUM_SAMPLE_BITS = 6;
177+ static const int sample_rates[NUM_SAMPLE_RATE];
178+
179+
180+ static const bits_pair sample_bits[NUM_SAMPLE_BITS];
181+
182+ typedef std::map<int,std::map<int,std::map<int,std::map<int,std::map<int,int> > > > > format_map_type;
183+
184+
185+ struct device_info
186+ {
187+
188+ device_info(Windows::Devices::Enumeration::DeviceInformation^ info);
189+ ~device_info();
190+
191+ std::wstring id_;
192+ std::wstring name_;
193+ std::wstring display_name_;
194+
195+ bool is_enabled_;
196+ bool is_selected_;
197+ bool is_default_;
198+
199+ format_map_type support_formats_;
200+ REFERENCE_TIME latency_minimum_;
201+ REFERENCE_TIME latency_default_;
202+ struct params_t
203+ {
204+ params_t()
205+ : exclusive_mode(false),event_mode(false),bits(16),valid_bits(16),sample_rate(44100),latency(0),channel(2)
206+ {}
207+ bool exclusive_mode;
208+ bool event_mode;
209+ int bits;
210+ int valid_bits;
211+ int sample_rate;
212+ REFERENCE_TIME latency;
213+ int channel;
214+ private:
215+ friend class boost::serialization::access;
216+ template<class Archive>
217+ void serialize(Archive& ar, const unsigned int version)
218+ {
219+ ar & BOOST_SERIALIZATION_NVP(exclusive_mode);
220+ ar & BOOST_SERIALIZATION_NVP(event_mode);
221+ ar & BOOST_SERIALIZATION_NVP(bits);
222+ ar & BOOST_SERIALIZATION_NVP(valid_bits);
223+ ar & BOOST_SERIALIZATION_NVP(sample_rate);
224+ ar & BOOST_SERIALIZATION_NVP(latency);
225+ ar & BOOST_SERIALIZATION_NVP(channel);
226+ }
227+ };
228+ params_t params;
229+ private:
230+ Windows::Devices::Enumeration::DeviceInformation^ device_info_;
231+ };
232+
233+ typedef std::vector<device_info> device_infos_t;
234+
235+ wasapi_device_manager();
236+ ~wasapi_device_manager();
237+
238+ device_info& current_output_device(){return output_device_infos_[output_device_index_];};
239+ device_info& current_input_device() {return input_device_infos_[input_device_index_];};
240+
241+ device_infos_t& output_device_infos() {return output_device_infos_;}
242+ device_infos_t& input_device_infos() {return input_device_infos_;}
243+
244+ void select_output_device(int index) { assert(index < output_device_infos_.size()) ; output_device_index_ = index;}
245+ void select_input_device(int index) { assert(index < input_device_infos_.size()) ; input_device_index_ = index;}
246+ int current_output_device_index() const {return output_device_index_;}
247+ int current_input_device_index() const {return input_device_index_;}
248+ static const std::wstring & base_directory() {return base_directory_;};
249+ private:
250+ void output_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo);
251+ void output_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj);
252+ void output_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo);
253+ void output_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo);
254+ void output_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj);
255+
256+ void input_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo);
257+ void input_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj);
258+ void input_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo);
259+ void input_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo);
260+ void input_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj);
261+
262+ int get_device_infos(Windows::Devices::Enumeration::DeviceClass data_flow, std::vector<device_info>& infos,const std::wstring& idd);
263+ int output_device_index_;
264+ int input_device_index_;
265+ std::vector<device_info> output_device_infos_;
266+ std::vector<device_info> input_device_infos_;
267+ static const std::wstring base_directory_;
268+ std::wstring config_path_;
269+ DeviceWatcherAdapter^ output_watcher_adapter_;
270+ DeviceWatcherAdapter^ input_watcher_adapter_;
271+ bool enum_completed_;
272+ };
273+
274+ // タイマーモードのポリシークラス
275+ struct wasapi_timer_policy
276+ {
277+ wasapi_timer_policy(REFERENCE_TIME & latency) : latency_(latency) {};
278+ void wait(){ Sleep(/*Concurrency::wait(*/latency_ / 20000L);}
279+ static const int STREAM_FLAG = 0;
280+ private:
281+ const REFERENCE_TIME& latency_;
282+ };
283+
284+ // イベントモードのポリシークラス
285+ struct wasapi_event_policy
286+ {
287+ wasapi_event_policy() :
288+ wait_events_(::CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE)) {}
289+
290+ void wait()
291+ {
292+
293+ WaitForSingleObjectEx(wait_events_.get(),INFINITE,FALSE);
294+ ;
295+ // Thread
296+ // Windows::UI::Core::CoreWindow::GetForCurrentThread()
297+ }
298+
299+ HANDLE event_handle(){return wait_events_.get();}
300+ static const int STREAM_FLAG = AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
301+ private:
302+ handle_holder wait_events_;
303+ };
304+
305+ // 排他モードのポリシークラス
306+ struct wasapi_exclusive_policy
307+ {
308+ static const AUDCLNT_SHAREMODE SHARE_MODE = AUDCLNT_SHAREMODE_EXCLUSIVE;
309+ };
310+
311+ // 共有モードのポリシークラス
312+ struct wasapi_shared_policy
313+ {
314+ static const AUDCLNT_SHAREMODE SHARE_MODE = AUDCLNT_SHAREMODE_SHARED;
315+ };
316+
317+ // レンダークライアントのポリシークラス
318+ struct render_client_policy
319+ {
320+ //typedef IAudioRenderClientPtr client_ptr_t;
321+ };
322+
323+ // キャプチャのポリシークラス
324+ struct capture_client_policy
325+ {
326+ //typedef IAudioCaptureClientPtr client_ptr_t;
327+ };
328+
329+ // キャプチャのポリシークラス
330+ struct loopback_capture_client_policy
331+ {
332+ //typedef IAudioCaptureClientPtr client_ptr_t;
333+ };
334+
335+ /// WASAPI処理クラス(デフォルト:共有・タイマーモード)
336+ template <typename ShareModePolicy = wasapi_shared_policy,typename DrivenPolicy = wasapi_timer_policy,typename IOClientPolicy = render_client_policy>
337+ struct wasapi_base : public audio_base
338+ {
339+ friend IOClientPolicy;
340+ //typedef typename IOClientPolicy::client_ptr_t client_ptr_t;
341+ typedef wasapi_base<ShareModePolicy,DrivenPolicy> this_type;
342+ //wasapi_base();
343+ wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params);
344+ //explicit wasapi_base(::WAVEFORMATEXTENSIBLE& wfx);
345+ virtual ~wasapi_base();
346+
347+ bool is_enabled () const {return is_enabled_;}
348+
349+ /// テスト用 サイン波データの生成
350+ void create_wave_data();
351+
352+ /// サウンド再生処理
353+ // bool play_buffer(BYTE* buffer);
354+ bool is_start(){ return is_start_; }
355+ // 出力用
356+ uint32_t get_buffer(BYTE** buffer,uint32_t size);
357+ // キャプチャ用
358+ uint32_t get_buffer(BYTE** buffer);
359+
360+ void release_buffer(uint32_t num_byte_written);
361+
362+ void start();
363+ void stop();
364+ void reset();
365+ void wait(){driven_policy_.wait();};
366+ uint32_t get_current_padding();
367+ uint64_t get_position() const
368+ {
369+ uint64_t pos = 0;
370+ audio_clock2_->GetPosition(&pos,0);
371+ return pos;
372+ };
373+ uint32_t get_buffer_byte_size () const { return buffer_size_ * num_of_frames_;}
374+ uint32_t get_frame_size() const {return num_of_frames_;}
375+ uint32_t get_buffer_size () const { return buffer_size_; }
376+ uint64_t get_buffer_duration() { return latency_;}
377+ uint32_t get_channel() { return mix_format_.Format.nChannels; }
378+ win32_error_exception* const result() {return exception_holder_.get(); }
379+
380+ private:
381+
382+ void init_io_client( boost::type<render_client_policy>)
383+ {
384+ // 再生クライアントの取得
385+ THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&render_client_)));
386+ };
387+
388+ void init_io_client(boost::type<capture_client_policy>)
389+ {
390+ // 再生クライアントの取得
391+ THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&capture_client_)));
392+ };
393+
394+ void init_audio_client(WAVEFORMATEXTENSIBLE& wfx);
395+ DrivenPolicy driven_policy_;
396+ void get_default_audio_client();
397+ void init(wasapi_device_manager::device_info& device,wasapi_device_manager::device_info::params_t& params);
398+ // IMMDeviceEnumeratorPtr device_collection_;
399+ wasapi_device_manager::device_info* current_device_;
400+ //Windows::Devices::Enumeration::DeviceInformation^ current_device_;
401+ IAudioClient2Ptr audio_client_;
402+ IAudioRenderClientPtr render_client_;
403+ IAudioCaptureClientPtr capture_client_;
404+ IAudioClockPtr audio_clock2_;
405+ //IAudioClockAdjustmentPtr audio_clock_adjustment_;
406+ //handle_holder buffer_control_event_;
407+ WAVEFORMATEXTENSIBLE mix_format_;
408+ bool is_enabled_;
409+ bool is_start_;
410+ boost::shared_ptr<win32_error_exception> exception_holder_;
411+ boost::uint32_t num_of_frames_;
412+ boost::uint32_t buffer_size_;
413+ uint64_t position_;
414+ std::vector<short> tone_buffer_;
415+ size_t buffer_in_periods_;// = buffer_size_ / periods_per_buffer_;
416+
417+ // バッファ中の区切り数(レイテンシ時間が何個あるか)
418+ static const uint32_t periods_per_buffer_ = 1;
419+ //= mpl::if_c<boost::is_same<this_type,wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy> >::value,
420+ // mpl::int_<1>,mpl::int_<1> >::type::value;
421+
422+ // 再生レイテンシ
423+ REFERENCE_TIME latency_;/* ms */
424+ REFERENCE_TIME actual_latency_;
425+ };
426+
427+ typedef wasapi_base<wasapi_shared_policy,wasapi_timer_policy> wasapi_shared_timer;
428+ typedef wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy> wasapi_exclusive_timer;
429+
430+ typedef wasapi_base<wasapi_shared_policy,wasapi_event_policy> wasapi_shared_event;
431+ typedef wasapi_base<wasapi_exclusive_policy,wasapi_event_policy> wasapi_exclusive_event;
432+
433+ typedef wasapi_base<wasapi_shared_policy,wasapi_timer_policy,capture_client_policy> wasapi_capture_shared_timer;
434+ typedef wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy,capture_client_policy> wasapi_capture_exclusive_timer;
435+
436+ typedef wasapi_base<wasapi_shared_policy,wasapi_event_policy,capture_client_policy> wasapi_capture_shared_event;
437+ typedef wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy> wasapi_capture_exclusive_event;
438+
439+
440+ struct ActivateAudioInterfaceCompletionHandler
441+ : public Microsoft::WRL::RuntimeClass< Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::ClassicCom >, Microsoft::WRL::FtmBase, IActivateAudioInterfaceCompletionHandler >
442+ {
443+ ActivateAudioInterfaceCompletionHandler() :
444+ hr_(S_OK),
445+ ptr_(nullptr),
446+ eventHolder_(::CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE)) {};
447+
448+ ~ActivateAudioInterfaceCompletionHandler(){};
449+
450+ // IActivateAudioInterfaceCompletionHandler
451+ STDMETHOD(ActivateCompleted)( IActivateAudioInterfaceAsyncOperation *operation )
452+ {
453+ HRESULT hr = S_OK;
454+ HRESULT hrActivateResult = S_OK;
455+ IUnknown *punkAudioInterface = nullptr;
456+ // Check for a successful activation result
457+ hr = operation->GetActivateResult( &hrActivateResult, &punkAudioInterface );
458+ if(SUCCEEDED(hr)){
459+ if (SUCCEEDED( hrActivateResult ))
460+ {
461+ hr_ = S_OK;
462+ // Get the pointer for the Audio Client
463+ punkAudioInterface->QueryInterface( IID_PPV_ARGS(&ptr_) );
464+ if( nullptr == ptr_ )
465+ {
466+ hr_ = E_FAIL;
467+ ::SetEvent(eventHolder_.get());
468+ return hr_;
469+ }
470+ ::SetEvent(eventHolder_.get());
471+ } else {
472+ hr_ = hr = hrActivateResult;
473+ ::SetEvent(eventHolder_.get());
474+ }
475+ } else {
476+ hr_ = hr;
477+ ::SetEvent(eventHolder_.get());
478+ }
479+ return hr;
480+ //operation
481+ // concurrency::wait(0);
482+ }
483+
484+ void wait()
485+ {
486+ ::WaitForSingleObjectEx(eventHolder_.get(),INFINITE,FALSE);
487+ }
488+
489+ HRESULT ResultCode() {return hr_;}
490+ IAudioClient2Ptr AudioClient(){return ptr_;}
491+ private:
492+ HRESULT hr_;
493+ sf::handle_holder eventHolder_;
494+ IAudioClient2Ptr ptr_;
495+ };
314496
315497 }
316498
--- a/wasapi2/wasapi2.rc
+++ b/wasapi2/wasapi2.rc
@@ -119,3 +119,5 @@ STRINGTABLE
119119 //
120120 LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN
121121 IDI_ICON1 ICON "directx.ico"
122+
123+
--- a/wasapi2/wasapi2.vcxproj
+++ b/wasapi2/wasapi2.vcxproj
@@ -42,12 +42,13 @@
4242 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
4343 <LinkIncremental>true</LinkIncremental>
4444 <IncludePath>H:\libs\libsamplerate-0.1.8\src;H:\libs\libsamplerate-0.1.8\Win32;$(IncludePath)</IncludePath>
45- <LibraryPath>H:\libs\libsamplerate-0.1.8\Win32\src\x64\Debug;H:\libs\libsamplerate-0.1.8\Win32\src\x64\Release;H:\satoshi_documents\documents\Visual Studio 2012\Projects\boostlib\x64\Debug;$(LibraryPath)</LibraryPath>
45+ <LibraryPath>H:\libs\libsamplerate-0.1.8\Win32\src\x64\Debug;H:\libs\libsamplerate-0.1.8\Win32\src\x64\Release;H:\satoshi_documents\documents\Visual Studio 2012\Projects\boostlib\x64\Debug;H:\libs\DirectXTK\Bin\Desktop\x64\Debug;$(LibraryPath)</LibraryPath>
46+ <ExecutablePath>H:\libs\DirectXTK\Bin\Desktop\x64\Debug;$(ExecutablePath)</ExecutablePath>
4647 </PropertyGroup>
4748 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
4849 <LinkIncremental>false</LinkIncremental>
4950 <IncludePath>H:\libs\libsamplerate-0.1.8\src;$(IncludePath)</IncludePath>
50- <LibraryPath>H:\libs\libsamplerate-0.1.8\Win32\src\x64\Release;H:\satoshi_documents\documents\Visual Studio 2012\Projects\boostlib\boostlib\x64\Release;$(LibraryPath)</LibraryPath>
51+ <LibraryPath>H:\libs\libsamplerate-0.1.8\Win32\src\x64\Release;H:\satoshi_documents\documents\Visual Studio 2012\Projects\boostlib\boostlib\x64\Release;H:\libs\DirectXTK\Bin\Desktop\x64\Debug;$(LibraryPath)</LibraryPath>
5152 </PropertyGroup>
5253 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
5354 <ClCompile>
@@ -62,6 +63,7 @@
6263 <CompileAsWinRT>true</CompileAsWinRT>
6364 <AdditionalUsingDirectories>C:\Program Files %28x86%29\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\Microsoft.VCLibs\11.0\References\CommonConfiguration\neutral;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
6465 <MinimalRebuild>false</MinimalRebuild>
66+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
6567 </ClCompile>
6668 <Link>
6769 <SubSystem>Windows</SubSystem>
--- a/wasapi2/wasapi_base.cpp
+++ b/wasapi2/wasapi_base.cpp
@@ -20,7 +20,7 @@ Boston, MA 02111-1307 USA
2020 ==============================================================================
2121 */
2222
23-#include "StdAfx.h"
23+#include "stdafx.h"
2424 #if _DEBUG
2525 #define _CRTDBG_MAP_ALLOC
2626 #include <crtdbg.h>
@@ -28,8 +28,12 @@ Boston, MA 02111-1307 USA
2828 #endif
2929 #include "audio_base.h"
3030 #include "wasapi.h"
31+#pragma comment(lib, "winmm.lib")
32+#pragma comment(lib, "Avrt.lib")
33+#pragma comment(lib, "Mmdevapi.lib")
3134
3235 using namespace std;
36+using namespace Microsoft::WRL;
3337
3438 namespace sf{
3539
@@ -42,7 +46,7 @@ namespace sf{
4246 wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params)
4347 : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_)
4448 {
45- init(wasapi_device_manager::instance()->output_device_infos().at(device_index).device_ptr,params);
49+ init(wasapi_device_manager::instance()->output_device_infos().at(device_index),params);
4650 }
4751
4852 // 共有・イベント・再生
@@ -50,7 +54,7 @@ namespace sf{
5054 wasapi_base<wasapi_shared_policy,wasapi_event_policy,render_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params)
5155 : is_enabled_(false),position_(0),is_start_(false),driven_policy_()
5256 {
53- init(wasapi_device_manager::instance()->output_device_infos().at(device_index).device_ptr,params);
57+ init(wasapi_device_manager::instance()->output_device_infos().at(device_index),params);
5458 audio_client_->SetEventHandle(driven_policy_.event_handle());
5559 }
5660
@@ -59,7 +63,7 @@ namespace sf{
5963 wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,render_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params)
6064 : is_enabled_(false),position_(0),is_start_(false),driven_policy_()
6165 {
62- init(wasapi_device_manager::instance()->output_device_infos().at(device_index).device_ptr,params);
66+ init(wasapi_device_manager::instance()->output_device_infos().at(device_index),params);
6367 audio_client_->SetEventHandle(driven_policy_.event_handle());
6468 }
6569
@@ -68,7 +72,7 @@ namespace sf{
6872 wasapi_base<wasapi_shared_policy,wasapi_timer_policy,capture_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params)
6973 : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_)
7074 {
71- init(wasapi_device_manager::instance()->input_device_infos().at(device_index).device_ptr,params);
75+ init(wasapi_device_manager::instance()->input_device_infos().at(device_index),params);
7276 }
7377
7478 // 排他・タイマ・キャプチャ
@@ -76,7 +80,7 @@ namespace sf{
7680 wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy,capture_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params)
7781 : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_)
7882 {
79- init(wasapi_device_manager::instance()->input_device_infos().at(device_index).device_ptr,params);
83+ init(wasapi_device_manager::instance()->input_device_infos().at(device_index),params);
8084 }
8185
8286 // 共有・イベント・キャプチャ
@@ -84,7 +88,7 @@ namespace sf{
8488 wasapi_base<wasapi_shared_policy,wasapi_event_policy,capture_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params)
8589 : is_enabled_(false),position_(0),is_start_(false),driven_policy_()
8690 {
87- init(wasapi_device_manager::instance()->input_device_infos().at(device_index).device_ptr,params);
91+ init(wasapi_device_manager::instance()->input_device_infos().at(device_index),params);
8892 audio_client_->SetEventHandle(driven_policy_.event_handle());
8993 }
9094
@@ -93,7 +97,7 @@ namespace sf{
9397 wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params)
9498 : is_enabled_(false),position_(0),is_start_(false),driven_policy_()
9599 {
96- init(wasapi_device_manager::instance()->input_device_infos().at(device_index).device_ptr,params);
100+ init(wasapi_device_manager::instance()->input_device_infos().at(device_index),params);
97101 audio_client_->SetEventHandle(driven_policy_.event_handle());
98102 }
99103
@@ -105,27 +109,35 @@ namespace sf{
105109 void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::get_default_audio_client()
106110 {
107111
108- current_device_ = wasapi_device_manager::instance()->current_output_device().device_ptr;
112+ current_device_ = &(wasapi_device_manager::instance()->current_output_device());
113+ {
114+ ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;
115+ IActivateAudioInterfaceAsyncOperation* asyncOp;
116+ ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());
117+ HRESULT hr = ActivateAudioInterfaceAsync(current_device_->id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);
118+ asyncOpPtr.Attach(asyncOp);
119+ if(SUCCEEDED(hr)){
120+ handler->wait();
121+ if(handler->ResultCode() == S_OK)
122+ {
123+ audio_client_ = handler->AudioClient();
124+ } else {
125+ throw win32_error_exception(handler->ResultCode());
126+ }
127+ } else {
128+ throw win32_error_exception(handler->ResultCode());
129+ }
130+ }
109131
110- // オーディオクライアントを取得
111- THROW_IF_ERR(
112- current_device_
113- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
114- NULL, reinterpret_cast<void **>(&audio_client_))
115- );
132+// ActivateAudioInterface(current_device_->id_.c_str(),__uuidof(IAudioClient2),&audio_client_);
116133 }
117134
118135 template<>
119136 void wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy>
120137 ::get_default_audio_client()
121138 {
122- current_device_ = wasapi_device_manager::instance()->current_input_device().device_ptr;
123- // オーディオクライアントを取得
124- THROW_IF_ERR(
125- current_device_
126- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
127- NULL, reinterpret_cast<void **>(&audio_client_))
128- );
139+ current_device_ = &(wasapi_device_manager::instance()->current_output_device());
140+// ActivateAudioInterface(current_device_->id_.c_str(),__uuidof(IAudioClient2),&audio_client_);
129141 }
130142
131143 // ==================================
@@ -133,22 +145,34 @@ namespace sf{
133145 // ==================================
134146
135147 template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy>
136- void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::init(IMMDevicePtr device,wasapi_device_manager::device_info::params_t& params)
148+ void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::init(wasapi_device_manager::device_info& device,wasapi_device_manager::device_info::params_t& params)
137149 {
138150 WAVEFORMATEXTENSIBLE wfx;
139151 bits_pair bits = {params.bits,params.valid_bits};
140152 make_wave_format(wfx,params.sample_rate,params.channel,bits);
141- latency_ = params.latency;//wasapi_device_manager::instance()->current_output_device().latency_default;
153+ latency_ = params.latency;//wasapi_device_manager::instance()->current_output_device().latency_default_;
142154
143155 // 代替フォーマット定義
144156 sf::co_task_memory<WAVEFORMATEX> alt_format;
145-
146- THROW_IF_ERR(
147- device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
148- NULL, reinterpret_cast<void **>(&audio_client_))
149- );
150-
151- current_device_ = device;
157+ {
158+ ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;
159+ IActivateAudioInterfaceAsyncOperation* asyncOp;
160+ ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());
161+ HRESULT hr = ActivateAudioInterfaceAsync(device.id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);
162+ asyncOpPtr.Attach(asyncOp);
163+ if(SUCCEEDED(hr)){
164+ handler->wait();
165+ if(handler->ResultCode() == S_OK)
166+ {
167+ audio_client_ = handler->AudioClient();
168+ } else {
169+ throw win32_error_exception(handler->ResultCode());
170+ }
171+ } else {
172+ throw win32_error_exception(handler->ResultCode());
173+ }
174+ }
175+ current_device_ = &device;
152176
153177 // 読みこもうとしているWAVファイルのフォーマットをサポートしているか?
154178 THROW_IF_ERR(audio_client_->IsFormatSupported(
@@ -187,11 +211,25 @@ namespace sf{
187211 THROW_IF_ERR(audio_client_->GetBufferSize(&buffer_size_));
188212 latency_ = actual_latency_ =
189213 (double)10000000 * (buffer_size_) / wfx.Format.nSamplesPerSec;
190- audio_client_.Release();
191- THROW_IF_ERR(
192- device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
193- NULL, reinterpret_cast<void **>(&audio_client_))
194- );
214+ audio_client_.Reset();
215+ {
216+ ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;
217+ IActivateAudioInterfaceAsyncOperation* asyncOp;
218+ ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());
219+ HRESULT hr = ActivateAudioInterfaceAsync(device.id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);
220+ asyncOpPtr.Attach(asyncOp);
221+ if(SUCCEEDED(hr)){
222+ handler->wait();
223+ if(handler->ResultCode() == S_OK)
224+ {
225+ audio_client_ = handler->AudioClient();
226+ } else {
227+ throw win32_error_exception(handler->ResultCode());
228+ }
229+ } else {
230+ throw win32_error_exception(handler->ResultCode());
231+ }
232+ }
195233 init_audio_client(wfx);
196234
197235 } else {
@@ -318,12 +356,12 @@ namespace sf{
318356 {
319357 audio_client_->Stop();
320358 audio_client_->Reset();
321- audio_client_.Release();
359+ audio_client_.Reset();
322360 }
323361 safe_release(render_client_);
324362 safe_release(capture_client_);
325- safe_release(current_device_);
326- // safe_release(device_enumerator_);
363+ //safe_release(current_device_);
364+ // safe_release(device_collection_);
327365 }
328366
329367 // ================================
--- a/wasapi2/wasapi_exclusive_timer.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
1-/*
2- ==============================================================================
3-
4- Copyright 2005-11 by Satoshi Fujiwara.
5-
6- async can be redistributed and/or modified under the terms of the
7- GNU General Public License, as published by the Free Software Foundation;
8- either version 2 of the License, or (at your option) any later version.
9-
10- async is distributed in the hope that it will be useful,
11- but WITHOUT ANY WARRANTY; without even the implied warranty of
12- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13- GNU General Public License for more details.
14-
15- You should have received a copy of the GNU General Public License
16- along with async; if not, visit www.gnu.org/licenses or write to the
17- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18- Boston, MA 02111-1307 USA
19-
20- ==============================================================================
21-*/
22-
23-#include "StdAfx.h"
24-#if _DEBUG
25-#define _CRTDBG_MAP_ALLOC
26-#include <crtdbg.h>
27-#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
28-#endif
29-#include "sf_memory.h"
30-#include "audio_base.h"
31-#include "wasapi.h"
32-
33-using namespace std;
34-
35-namespace sf{
36-
37- wasapi_exclusive_timer::wasapi_exclusive_timer(int device_index,wasapi_device_manager::device_info::current_device_params& params)
38- : is_enabled_(false),position_(0),is_start_(false)
39- {
40- current_device_ = wasapi_device_manager::instance()->output_device_infos().at(device_index).device_ptr;
41- // オーディオクライアントを取得
42- THROW_IF_ERR(
43- current_device_
44- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
45- NULL, reinterpret_cast<void **>(&audio_client_))
46- );
47- WAVEFORMATEXTENSIBLE w;
48- bits_pair bits = {params.bits,params.valid_bits};
49- make_wave_format(w,params.sample_rate,params.channel,bits);
50- latency_ = params.latency;//wasapi_device_manager::instance()->current_output_device().latency_default;
51- init(w);
52- }
53-
54- wasapi_exclusive_timer::wasapi_exclusive_timer()
55- : is_enabled_(false),position_(0),is_start_(false)
56- {
57- co_task_memory<WAVEFORMATEX> wfx;
58- get_default_audio_client();
59- WAVEFORMATEXTENSIBLE w;
60- wasapi_device_manager::device_info::current_device_params& params(wasapi_device_manager::instance()->current_input_device().current_params);
61- bits_pair bits = {params.bits,params.valid_bits};
62- make_wave_format(w,params.sample_rate,params.channel,bits);
63- latency_ = wasapi_device_manager::instance()->current_output_device().latency_default;
64-
65- //uint64_t freq;
66- //audio_client_->GetMixFormat(&wfx);
67- //WAVEFORMATEXTENSIBLE* w(reinterpret_cast<WAVEFORMATEXTENSIBLE*>(wfx.get()));
68- //w->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
69- //w->Format.wBitsPerSample = 16;
70- //w->Format.nBlockAlign = (w->Format.wBitsPerSample / 8) * w->Format.nChannels;
71- //w->Format.nAvgBytesPerSec = w->Format.nSamplesPerSec *w->Format.nBlockAlign;
72- //w->Samples.wValidBitsPerSample = 16;
73- init(w);
74- }
75-
76- void wasapi_exclusive_timer::get_default_audio_client()
77- {
78- //// IMMDeviceEnumeratorの取得
79- //THROW_IF_ERR(
80- // CoCreateInstance(
81- // __uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
82- // IID_PPV_ARGS(&device_enumerator_)));
83-
84- //// デフォルトのオーディオデバイスを取得する
85- //THROW_IF_ERR(
86- // device_enumerator_
87- // ->GetDefaultAudioEndpoint(eRender,eMultimedia,&current_device_)
88- // );
89-
90- current_device_ = wasapi_device_manager::instance()->current_output_device().device_ptr;
91-
92- // オーディオクライアントを取得
93- THROW_IF_ERR(
94- current_device_
95- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
96- NULL, reinterpret_cast<void **>(&audio_client_))
97- );
98- }
99-
100- void wasapi_exclusive_timer::init(::WAVEFORMATEXTENSIBLE& wfx)
101- {
102- // 代替フォーマット定義
103- sf::co_task_memory<WAVEFORMATEX> alt_format;
104-
105- // 読みこもうとしているWAVファイルのフォーマットをサポートしているか?
106- HRESULT hr = audio_client_->IsFormatSupported(
107- AUDCLNT_SHAREMODE_EXCLUSIVE ,&wfx.Format,&alt_format);
108-
109- // 再生クライアントの初期化
110- REFERENCE_TIME buffer_period = latency_ ;
111-
112- REFERENCE_TIME buffer_duration = buffer_period * periods_per_buffer_;
113-
114- THROW_IF_ERR(audio_client_->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE ,
115- AUDCLNT_STREAMFLAGS_NOPERSIST,
116- buffer_duration,
117- buffer_period,
118- &(wfx.Format),
119- NULL));
120-
121- REFERENCE_TIME psl;
122- THROW_IF_ERR(audio_client_->GetStreamLatency(&psl));
123-#ifdef _DEBUG
124- wdout << L"StreamLatency:" << psl << endl;
125-#endif
126-
127- // バッファサイズの取得
128- THROW_IF_ERR(audio_client_->GetBufferSize(&buffer_size_));
129-
130- // 再生クライアントの取得
131- THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&audio_render_client_)));
132-
133-
134- num_of_frames_ = wfx.Format.nBlockAlign;
135- mix_format_ = wfx;
136- buffer_in_periods_ = buffer_size_ / periods_per_buffer_;
137-
138- is_enabled_ = true;
139- }
140-
141- wasapi_exclusive_timer::wasapi_exclusive_timer(::WAVEFORMATEXTENSIBLE& wfx)
142- : is_enabled_(false),position_(0),is_start_(false)/*,buffer_control_event_(::CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE))*/
143- {
144-
145- try {
146- // thread_priority_.set_priority(AVRT_PRIORITY_NORMAL);
147-
148- // WASAPIの初期化処理
149-
150- get_default_audio_client();
151- init(wfx);
152-
153- } catch (win32_error_exception& e)
154- {
155- exception_holder_.reset(new win32_error_exception(e.hresult()));
156- is_enabled_ = false;
157- } catch(...) {
158- is_enabled_ = false;
159- }
160- }
161-
162- wasapi_exclusive_timer::~wasapi_exclusive_timer()
163- {
164-// safe_release(audio_clock_adjustment_);
165-
166- // WASAPIの終了処理
167- if(audio_client_)
168- {
169- audio_client_->Stop();
170- audio_client_->Reset();
171- safe_release(audio_render_client_);
172- audio_client_.Release();
173- }
174-
175- safe_release(current_device_);
176-// safe_release(device_enumerator_);
177- }
178-
179- void wasapi_exclusive_timer::play_buffer(BYTE* source_buffer)
180- {
181- BYTE* buffer;
182-
183- if(!is_start_)
184- {
185-
186- // 最初にバッファを埋める
187- THROW_IF_ERR(audio_render_client_->GetBuffer(buffer_size_,&buffer));
188- ::CopyMemory(buffer,source_buffer,get_buffer_byte_size());
189-
190- // レイテンシ時間*バッファ数分進める
191- THROW_IF_ERR(audio_render_client_->ReleaseBuffer(buffer_size_,0));
192-
193- // 再生開始
194- THROW_IF_ERR(audio_client_->Start());
195- is_start_ = true;
196- return;
197- }
198-
199-
200- // レイテンシ時間だけ待つ
201- Sleep(latency_ / 10000 );
202-
203- uint32_t padding;
204- uint32_t frames_available;
205- uint32_t count_period = periods_per_buffer_;
206- while(count_period > 0)
207- {
208- // パディングを求める。
209- THROW_IF_ERR(audio_client_->GetCurrentPadding(&padding));
210- frames_available = buffer_size_ - padding;
211-
212- // パディングを除いた部分のバッファを埋める。
213- // パディングを除いた部分のサイズがbuffer_in_periods_より小さい場合はつぎにまわす。
214- // パディングを除いた部分を一気に埋めようとしたけどできなかった。。
215- while(buffer_in_periods_ <= frames_available && count_period > 0 )
216- {
217- THROW_IF_ERR(audio_render_client_->GetBuffer(buffer_in_periods_,&buffer));
218- ::CopyMemory(buffer,source_buffer,buffer_in_periods_ * num_of_frames_);
219- THROW_IF_ERR(audio_render_client_->ReleaseBuffer(buffer_in_periods_,0));
220- // レイテンシ時間だけ進める
221- source_buffer += buffer_in_periods_ * num_of_frames_;
222- --count_period;
223- // パディングを再度求める
224- THROW_IF_ERR(audio_client_->GetCurrentPadding(&padding));
225- frames_available = buffer_size_ - padding;
226- }
227-
228- if(count_period > 0)
229- {
230- Sleep(latency_ / 10000);
231- }
232- }
233- }
234- void wasapi_exclusive_timer::reset()
235- {
236- THROW_IF_ERR(audio_client_->Reset());
237- }
238- void wasapi_exclusive_timer::stop() {
239- //再生停止
240- if(is_start_)
241- {
242- THROW_IF_ERR(audio_client_->Stop());
243- reset();
244- is_start_ = false;
245-
246- };
247- }
248-}
--- a/wasapi2/wasapi_manager.cpp
+++ b/wasapi2/wasapi_manager.cpp
@@ -1,26 +1,26 @@
11 /*
2- ==============================================================================
2+==============================================================================
33
4- Copyright 2005-11 by Satoshi Fujiwara.
4+Copyright 2005-11 by Satoshi Fujiwara.
55
6- async can be redistributed and/or modified under the terms of the
7- GNU General Public License, as published by the Free Software Foundation;
8- either version 2 of the License, or (at your option) any later version.
6+async can be redistributed and/or modified under the terms of the
7+GNU General Public License, as published by the Free Software Foundation;
8+either version 2 of the License, or (at your option) any later version.
99
10- async is distributed in the hope that it will be useful,
11- but WITHOUT ANY WARRANTY; without even the implied warranty of
12- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13- GNU General Public License for more details.
10+async is distributed in the hope that it will be useful,
11+but WITHOUT ANY WARRANTY; without even the implied warranty of
12+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+GNU General Public License for more details.
1414
15- You should have received a copy of the GNU General Public License
16- along with async; if not, visit www.gnu.org/licenses or write to the
17- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18- Boston, MA 02111-1307 USA
15+You should have received a copy of the GNU General Public License
16+along with async; if not, visit www.gnu.org/licenses or write to the
17+Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18+Boston, MA 02111-1307 USA
1919
20- ==============================================================================
20+==============================================================================
2121 */
2222
23-#include "StdAfx.h"
23+#include "stdafx.h"
2424 #if _DEBUG
2525 #define _CRTDBG_MAP_ALLOC
2626 #include <crtdbg.h>
@@ -29,394 +29,510 @@
2929 #include "sf_memory.h"
3030 #include "audio_base.h"
3131 #include "wasapi.h"
32-#include "application.h"
33-using namespace boost;
32+//#include "application.h"
33+//using namespace boost;
3434 using namespace std;
35-namespace sf {
36- const int wasapi_device_manager::sample_rates[NUM_SAMPLE_RATE] = {8000,11025,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000};
37- const bits_pair wasapi_device_manager::sample_bits[NUM_SAMPLE_BITS] = {{8,8},{16,16},{24,24},{32,24},{32,32},{32,WAVE_FORMAT_IEEE_FLOAT}};
38-
39- void make_wave_format(WAVEFORMATEXTENSIBLE& format,int sample_rate,int channels,bits_pair b,uint32_t type,const GUID& sub_type)
40- {
41- ZeroMemory(&format,sizeof(WAVEFORMATEXTENSIBLE));
42- format.Format.wFormatTag = type;
43- format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
44- format.SubFormat = sub_type;
45- format.Format.nSamplesPerSec = sample_rate;
46- format.Format.nChannels = channels;
47- format.Format.wBitsPerSample = b.bits_per_sample;
48- format.Format.nBlockAlign = (format.Format.wBitsPerSample / 8) * format.Format.nChannels;
49- format.Format.nAvgBytesPerSec = format.Format.nSamplesPerSec * format.Format.nBlockAlign;
50- format.Samples.wValidBitsPerSample = b.valid_bits_per_sample;
51-
52- format.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
53- };
54-
55- void make_wave_format(WAVEFORMATEX& format,int sample_rate,int channels,int bits,uint32_t type)
56- {
57- ZeroMemory(&format,sizeof(WAVEFORMATEX));
58- format.wFormatTag = type;
59- format.nSamplesPerSec = sample_rate;
60- format.nChannels = channels;
61- format.wBitsPerSample = bits;
62- format.nBlockAlign = (format.wBitsPerSample / 8) * format.nChannels;
63- format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
64- };
65-
66- struct prop_variant
67- {
68- prop_variant()
69- {
70- PropVariantInit(&value_);
71- }
72-
73- ~prop_variant()
74- {
75- PropVariantClear(&value_);
76- }
77-
78- PROPVARIANT* get(){ return &value_;};
79-
80- PROPVARIANT* operator &(){return get();}
81-
82- operator PROPVARIANT*() {return get();}
83-
84- private:
85- PROPVARIANT value_;
86- };
87-
88-wasapi_device_manager::wasapi_device_manager()
89- : output_device_index_(0),input_device_index_(0)
90-{
91- wstring p = application::instance()->base_directory() + L"\\wasapi_device_manager.config.xml";
92- filesystem::wpath config_path(p);
93-
94- std::wstring output_id;
95- std::wstring input_id;
96-
97- if(filesystem::exists(config_path))
98- {
99- try {
100- filesystem::wifstream f(config_path);
101- archive::xml_wiarchive ar(f);
102- ar & boost::serialization::make_nvp("output_device_id",output_id);
103- ar & boost::serialization::make_nvp("input_device_id" ,input_id);
104- } catch(...)
105- {
106- output_id = input_id = L"";
107- filesystem::remove(config_path);
108- }
109- }
110-
111- // IMMDeviceEnumeratorの取得
112- THROW_IF_ERR(
113- CoCreateInstance(
114- __uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
115- IID_PPV_ARGS(&device_enumerator_)));
116-
117- // 出力エンドポイントの取得
118- output_device_index_ = get_device_infos(eRender,output_device_infos_,output_id);
119-
120- // 出力エンドポイントの能力を調査する
121- for(int d = 0;d < output_device_infos_.size();++d)
122- {
123- IAudioClientPtr c;
124- // オーディオクライアントを取得
125- THROW_IF_ERR(
126- output_device_infos_[d].device_ptr
127- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
128- NULL, reinterpret_cast<void **>(&c))
129- );
130-
131- c->GetDevicePeriod(&(output_device_infos_[d].latency_default),&(output_device_infos_[d].latency_minimum));
132- if(output_device_infos_[d].params.latency == 0
133- || output_device_infos_[d].params.latency < output_device_infos_[d].latency_minimum )
134- {
135- output_device_infos_[d].params.latency = output_device_infos_[d].latency_default;
136- }
35+using namespace Windows::Foundation;
36+using namespace Windows::Foundation::Collections;
37+using namespace Windows::Devices::Enumeration;
38+using namespace Windows::Media::Devices;
39+using namespace Concurrency;
40+using namespace Platform;
41+using namespace Microsoft::WRL;
13742
43+namespace sf {
44+ const wstring wasapi_device_manager::base_directory_(L""/* Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data() */);
45+ const int wasapi_device_manager::sample_rates[NUM_SAMPLE_RATE] = {8000,11025,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000};
46+ const bits_pair wasapi_device_manager::sample_bits[NUM_SAMPLE_BITS] = {{8,8},{16,16},{24,24},{32,24},{32,32},{32,WAVE_FORMAT_IEEE_FLOAT}};
47+
48+ void make_wave_format(WAVEFORMATEXTENSIBLE& format,int sample_rate,int channels,bits_pair b,uint32_t type,const GUID& sub_type)
49+ {
50+ ZeroMemory(&format,sizeof(WAVEFORMATEXTENSIBLE));
51+ format.Format.wFormatTag = type;
52+ format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
53+ format.SubFormat = sub_type;
54+ format.Format.nSamplesPerSec = sample_rate;
55+ format.Format.nChannels = channels;
56+ format.Format.wBitsPerSample = b.bits_per_sample;
57+ format.Format.nBlockAlign = (format.Format.wBitsPerSample / 8) * format.Format.nChannels;
58+ format.Format.nAvgBytesPerSec = format.Format.nSamplesPerSec * format.Format.nBlockAlign;
59+ format.Samples.wValidBitsPerSample = b.valid_bits_per_sample;
60+
61+ format.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
62+ };
63+
64+ void make_wave_format(WAVEFORMATEX& format,int sample_rate,int channels,int bits,uint32_t type)
65+ {
66+ ZeroMemory(&format,sizeof(WAVEFORMATEX));
67+ format.wFormatTag = type;
68+ format.nSamplesPerSec = sample_rate;
69+ format.nChannels = channels;
70+ format.wBitsPerSample = bits;
71+ format.nBlockAlign = (format.wBitsPerSample / 8) * format.nChannels;
72+ format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
73+ };
74+
75+ struct prop_variant
76+ {
77+ prop_variant()
78+ {
79+ PropVariantInit(&value_);
80+ }
81+
82+ ~prop_variant()
83+ {
84+ PropVariantClear(&value_);
85+ }
86+
87+ PROPVARIANT* get(){ return &value_;};
88+
89+ PROPVARIANT* operator &(){return get();}
90+
91+ operator PROPVARIANT*() {return get();}
92+
93+ private:
94+ PROPVARIANT value_;
95+ };
96+
97+
98+ wasapi_device_manager::wasapi_device_manager()
99+ : output_device_index_(0),input_device_index_(0),enum_completed_(false)
100+ {
101+
102+ config_path_.append(base_directory_).append(L"\\wasapi_device_manager.config.xml");
103+ boost::filesystem::wpath config_path(config_path_);
104+
105+ std::wstring output_id;
106+ std::wstring input_id;
107+
108+ if(boost::filesystem::exists(config_path))
109+ {
110+ try {
111+ boost::filesystem::wifstream f(config_path);
112+ boost::archive::xml_wiarchive ar(f);
113+ ar & boost::serialization::make_nvp("output_device_id",output_id);
114+ ar & boost::serialization::make_nvp("input_device_id" ,input_id);
115+ } catch(...)
116+ {
117+ output_id = input_id = L"";
118+ boost::filesystem::remove(config_path);
119+ }
120+ }
121+
122+ //watcher_ = DeviceInformation::CreateWatcher();
123+ //adapter_ = ref new typed_event_handler_adapter<DeviceWatcher^,DeviceInformation^>(boost::bind(&wasapi_device_manager::added,this,_1,_2));
124+ // watcher_->Added += adapter_->get();
125+ //watcher_->Added += (ref new typed_event_handler_adapter<DeviceWatcher^,DeviceInformation^>(boost::bind(&wasapi_device_manager::added,this,_1,_2)))->get();
126+ //watcher_->Start();
127+
128+ output_watcher_adapter_ = ref new DeviceWatcherAdapter(en::DeviceClass::AudioRender);
129+ output_watcher_adapter_->added().connect(boost::bind(&wasapi_device_manager::output_added,this,_1,_2));
130+ output_watcher_adapter_->enumration_completed().connect(boost::bind(&wasapi_device_manager::output_enumeration_completed,this,_1,_2));
131+ output_watcher_adapter_->removed().connect(boost::bind(&wasapi_device_manager::output_removed,this,_1,_2));
132+ output_watcher_adapter_->updated().connect(boost::bind(&wasapi_device_manager::output_updated,this,_1,_2));
133+ output_watcher_adapter_->stopped().connect(boost::bind(&wasapi_device_manager::output_stopped,this,_1,_2));
134+ output_watcher_adapter_->start();
135+
136+ input_watcher_adapter_ = ref new DeviceWatcherAdapter(en::DeviceClass::AudioCapture);
137+ input_watcher_adapter_->added().connect(boost::bind(&wasapi_device_manager::input_added,this,_1,_2));
138+ input_watcher_adapter_->enumration_completed().connect(boost::bind(&wasapi_device_manager::input_enumeration_completed,this,_1,_2));
139+ input_watcher_adapter_->removed().connect(boost::bind(&wasapi_device_manager::input_removed,this,_1,_2));
140+ input_watcher_adapter_->updated().connect(boost::bind(&wasapi_device_manager::input_updated,this,_1,_2));
141+ input_watcher_adapter_->stopped().connect(boost::bind(&wasapi_device_manager::input_stopped,this,_1,_2));
142+ input_watcher_adapter_->start();
143+
144+ //// IMMDeviceEnumeratorの取得
145+ //THROW_IF_ERR(
146+ // CoCreateInstance(
147+ // __uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
148+ // IID_PPV_ARGS(&device_collection_)));
149+ //task<DeviceInformationCollection^> t(DeviceInformation::FindAllAsync(DeviceClass::AudioRender));
150+ //device_collection_ = t.get();
151+
152+ // 出力エンドポイントの取得
153+ /*
154+ output_device_index_ = get_device_infos(Windows::Devices::Enumeration::DeviceClass::AudioRender,output_device_infos_,output_id);
155+ // 出力エンドポイントの能力を調査する
156+ for(int d = 0;d < output_device_infos_.size();++d)
157+ {
158+ IAudioClient2Ptr c;
159+ // オーディオクライアントを取得
160+ // THROW_IF_ERR(ActivateAudioInterface(output_device_infos_[d].id_.c_str(),__uuidof(IAudioClient2),&c));
161+ {
162+ ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;
163+ IActivateAudioInterfaceAsyncOperation* asyncOp;
164+ ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());
165+ HRESULT hr = ActivateAudioInterfaceAsync(output_device_infos_[d].id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);
166+ asyncOpPtr.Attach(asyncOp);
167+ if(SUCCEEDED(hr)){
168+ handler->wait();
169+ if(handler->ResultCode() == S_OK)
170+ {
171+ c = handler->AudioClient();
172+ } else {
173+ throw win32_error_exception(handler->ResultCode());
174+ }
175+ } else {
176+ throw win32_error_exception(handler->ResultCode());
177+ }
178+ }
179+ c->GetDevicePeriod(&(output_device_infos_[d].latency_default_),&(output_device_infos_[d].latency_minimum_));
180+ if(output_device_infos_[d].params.latency == 0
181+ || output_device_infos_[d].params.latency < output_device_infos_[d].latency_minimum_ )
182+ {
183+ output_device_infos_[d].params.latency = output_device_infos_[d].latency_default_;
184+ }
185+
186+ #ifdef _DEBUG
187+ wdout << output_device_infos_[d].name_ << endl;
188+ wdout << boost::wformat(L"latency default:%d min:%d") % output_device_infos_[d].latency_default_ % output_device_infos_[d].latency_minimum_ << endl;
189+ #endif
190+ for(int bits = 0;bits < NUM_SAMPLE_BITS;++bits)
191+ {
192+ for(int channel = 1;channel < 3;++channel)
193+ {
194+ for(int rate = 0;rate < NUM_SAMPLE_RATE;++rate)
195+ {
196+ sf::co_task_memory<WAVEFORMATEXTENSIBLE> a,a1;
197+ WAVEFORMATEXTENSIBLE f;
198+
199+ // make_wave_fomat(f,sample_rates[rate],channel,sample_bits[bits]);
200+ if(sample_bits[bits].valid_bits_per_sample == WAVE_FORMAT_IEEE_FLOAT)
201+ {
202+ bits_pair b ={sample_bits[bits].bits_per_sample,sample_bits[bits].bits_per_sample};
203+ make_wave_format(f,sample_rates[rate],channel,b,WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
204+ } else {
205+ make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_PCM);
206+ }
207+
208+ // 排他モード
209+ HRESULT hr = c->IsFormatSupported(
210+ AUDCLNT_SHAREMODE_EXCLUSIVE,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a));
211+ if(hr == S_OK){
212+ output_device_infos_[d].support_formats_[AUDCLNT_SHAREMODE_EXCLUSIVE][ sample_bits[bits].bits_per_sample ][sample_bits[bits].valid_bits_per_sample][channel][sample_rates[rate]] = 0;
213+ #ifdef _DEBUG
214+ wdout << boost::wformat(L"|exc |bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|") % sample_bits[bits].bits_per_sample % sample_bits[bits].valid_bits_per_sample % channel % sample_rates[rate] % (hr == S_OK?L"OK":L"NG") << endl;
215+ #endif }
216+
217+ // make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE);
218+ // 共有モード
219+ hr = c->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a1));
220+ if(hr == S_OK){
221+ output_device_infos_[d]
222+ .support_formats_
223+ [AUDCLNT_SHAREMODE_SHARED]
224+ [ sample_bits[bits].bits_per_sample ]
225+ [sample_bits[bits].valid_bits_per_sample]
226+ [channel][sample_rates[rate]]
227+ = 0;
228+ #ifdef _DEBUG
229+ wdout << boost::wformat(L"|share|bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|")
230+ % sample_bits[bits].bits_per_sample
231+ % sample_bits[bits].valid_bits_per_sample
232+ % channel % sample_rates[rate]
233+ % (hr == S_OK?L"OK":L"NG") << endl;
234+
235+ #endif
236+ }
237+ }
238+ }
239+ }
240+ #ifdef _DEBUG
241+ wdout << "-------------------------------" << std::endl;
242+ #endif
243+ }
244+ // safe_release(c);
245+ }
246+
247+ // 入力エンドポイントの取得
248+ input_device_index_ = get_device_infos(DeviceClass::AudioCapture,input_device_infos_,input_id);
249+ // 出力エンドポイントの能力を調査する
250+ for(int d = 0;d < input_device_infos_.size();++d)
251+ {
252+ IAudioClient2Ptr c;
253+ // オーディオクライアントを取得
254+ // THROW_IF_ERR(ActivateAudioInterface(input_device_infos_[d].id_.c_str(),__uuidof(IAudioClient2),&c) );
255+ {
256+ ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;
257+ IActivateAudioInterfaceAsyncOperation* asyncOp;
258+ ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());
259+ HRESULT hr = ActivateAudioInterfaceAsync(input_device_infos_[d].id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);
260+ asyncOpPtr.Attach(asyncOp);
261+ if(SUCCEEDED(hr)){
262+ handler->wait();
263+ if(handler->ResultCode() == S_OK)
264+ {
265+ c = handler->AudioClient();
266+ } else {
267+ throw win32_error_exception(handler->ResultCode());
268+ }
269+ } else {
270+ throw win32_error_exception(handler->ResultCode());
271+ }
272+ }
273+ c->GetDevicePeriod(&(input_device_infos_[d].latency_default_),&(input_device_infos_[d].latency_minimum_));
274+ if(input_device_infos_[d].params.latency == 0 || input_device_infos_[d].params.latency < input_device_infos_[d].latency_minimum_ ){
275+ input_device_infos_[d].params.latency = input_device_infos_[d].latency_default_;
276+ }
277+
278+ #ifdef _DEBUG
279+ wdout << input_device_infos_[d].display_name_ << endl;
280+ wdout << boost::wformat(L"latency default:%d min:%d") % input_device_infos_[d].latency_default_ % input_device_infos_[d].latency_minimum_ << endl;
281+ #endif
282+ for(int bits = 0;bits < NUM_SAMPLE_BITS;++bits)
283+ {
284+ for(int channel = 1;channel < 3;++channel)
285+ {
286+ for(int rate = 0;rate < NUM_SAMPLE_RATE;++rate)
287+ {
288+ sf::co_task_memory<WAVEFORMATEXTENSIBLE> a,a1;
289+ WAVEFORMATEXTENSIBLE f;
290+
291+ // make_wave_fomat(f,sample_rates[rate],channel,sample_bits[bits]);
292+ if(sample_bits[bits].valid_bits_per_sample == WAVE_FORMAT_IEEE_FLOAT)
293+ {
294+ bits_pair b ={sample_bits[bits].bits_per_sample,sample_bits[bits].bits_per_sample};
295+ make_wave_format(f,sample_rates[rate],channel,b,WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
296+ } else {
297+ make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_PCM);
298+ }
299+
300+ // 排他モード
301+ HRESULT hr = c->IsFormatSupported(
302+ AUDCLNT_SHAREMODE_EXCLUSIVE,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a));
303+ if(hr == S_OK){
304+ input_device_infos_[d]
305+ .support_formats_
306+ [AUDCLNT_SHAREMODE_EXCLUSIVE]
307+ [ sample_bits[bits].bits_per_sample ]
308+ [sample_bits[bits].valid_bits_per_sample]
309+ [channel]
310+ [sample_rates[rate]] = 0;
311+ #ifdef _DEBUG
312+ wdout << boost::wformat(L"|exc |bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|")
313+ % sample_bits[bits].bits_per_sample
314+ % sample_bits[bits].valid_bits_per_sample
315+ % channel % sample_rates[rate]
316+ % (hr == S_OK?L"OK":L"NG") << endl;
317+ #endif }
318+
319+ // make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE);
320+ // 共有モード
321+ hr = c->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a1));
322+ if(hr == S_OK){
323+ input_device_infos_[d].
324+ support_formats_
325+ [AUDCLNT_SHAREMODE_SHARED]
326+ [sample_bits[bits].bits_per_sample ]
327+ [sample_bits[bits].valid_bits_per_sample]
328+ [channel]
329+ [sample_rates[rate]] = 0;
330+ #ifdef _DEBUG
331+ wdout << boost::wformat(L"|share|bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|")
332+ % sample_bits[bits].bits_per_sample
333+ % sample_bits[bits].valid_bits_per_sample
334+ % channel
335+ % sample_rates[rate]
336+ % (hr == S_OK?L"OK":L"NG") << endl;
337+
338+ #endif
339+ }
340+ }
341+ }
342+ }
343+ #ifdef _DEBUG
344+ wdout << "-------------------------------" << std::endl;
345+ #endif
346+ }
347+ // safe_release(c);
348+ }
349+ */
350+ }//
351+
352+ int wasapi_device_manager::get_device_infos(DeviceClass data_flow, std::vector<device_info>& infos,const std::wstring& idd)
353+ {
354+
355+ // 対象デバイスを列挙する
356+ task<DeviceInformationCollection^> t((DeviceInformation::FindAllAsync(data_flow)));
357+ t.wait();
358+ DeviceInformationCollection^ collection = t.get();
359+ int current_index = 0;
360+ bool found = false;
361+ Platform::String^ default_id = ref new Platform::String();
362+ switch(data_flow)
363+ {
364+ case Windows::Devices::Enumeration::DeviceClass::AudioRender:
365+ default_id = MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
366+ break;
367+ case Windows::Devices::Enumeration::DeviceClass::AudioCapture:
368+ default_id = MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default);
369+ break;
370+ }
371+
372+
373+ for(int i = 0 ,end = collection->Size;i < end;++i)
374+ {
375+ DeviceInformation^ info = collection->GetAt(i);
376+ infos.push_back(device_info(info));
377+ if(info->Id == default_id)
378+ {
379+ infos[i].is_default_ = true;
380+ }
381+
382+ if(idd == wstring(info->Id->Data()) )
383+ {
384+ infos[i].is_selected_ = true;
385+ current_index = i;
386+ found = true;
387+ }
388+ }
389+
390+ if(!found)
391+ {
392+ for(int i = 0,end = infos.size();i < end;++i)
393+ {
394+ if(infos[i].is_default_)
395+ {
396+ current_index = i;
397+ infos[i].is_selected_ = true;
398+ }
399+ }
400+
401+ }
402+ return current_index;
403+ }
404+
405+ wasapi_device_manager::~wasapi_device_manager()
406+ {
407+ input_watcher_adapter_->stop();
408+ output_watcher_adapter_->stop();
409+ //for(int i = 0; i <
410+ //safe_release(device_collection_);
411+ //safe_release(device_collection_);
412+ //safe_release(device_collection_);
413+
414+ // 設定の保存
415+ try{
416+ boost::filesystem::wpath config_path(config_path_);
417+ boost::filesystem::wofstream f(config_path,std::ios_base::out | std::ios_base::trunc);
418+ boost::archive::xml_woarchive ar(f);
419+ ar & boost::serialization::make_nvp("output_device_id",current_output_device().id_);
420+ ar & boost::serialization::make_nvp("input_device_id" ,current_input_device().id_);
421+ }catch(...) {
422+
423+ }
424+
425+ }
426+
427+ wasapi_device_manager::device_info::device_info
428+ (DeviceInformation^ info)
429+ : id_(info->Id->Data()),
430+ name_(info->Name->Data()),
431+ display_name_(dynamic_cast<String^>(info->Properties->Lookup(L"System.ItemNameDisplay"))->Data()),
432+ is_enabled_(info->IsEnabled),is_selected_(false),is_default_(info->IsDefault)
433+ {
434+ boost::filesystem::wpath
435+ config_path(wasapi_device_manager::base_directory() + L"\\" + id_ + L".xml");
436+ if(boost::filesystem::exists(config_path))
437+ {
438+ try{
439+ boost::filesystem::wifstream ifile(config_path);
440+ boost::archive::xml_wiarchive ar(ifile);
441+ ar >> BOOST_SERIALIZATION_NVP(params);
442+ } catch (...)
443+ {
444+ // ファイル読み込みに問題がある場合はファイルを消す。
445+ boost::filesystem::remove(config_path);
446+ }
447+ }
138448 #ifdef _DEBUG
139- wdout << output_device_infos_[d].device_friendly_name << endl;
140- wdout << wformat(L"latency default:%d min:%d") % output_device_infos_[d].latency_default % output_device_infos_[d].latency_minimum << endl;
449+ wdout << L"================================================" << std::endl;
450+ wdout << id_ << L"\n" << display_name_ << std::endl;
451+ wdout << params.latency << std::endl;
452+ wdout << L"================================================" << std::endl;
141453 #endif
142- for(int bits = 0;bits < NUM_SAMPLE_BITS;++bits)
143- {
144- for(int channel = 1;channel < 3;++channel)
145- {
146- for(int rate = 0;rate < NUM_SAMPLE_RATE;++rate)
147- {
148- sf::co_task_memory<WAVEFORMATEXTENSIBLE> a,a1;
149- WAVEFORMATEXTENSIBLE f;
150-
151-// make_wave_fomat(f,sample_rates[rate],channel,sample_bits[bits]);
152- if(sample_bits[bits].valid_bits_per_sample == WAVE_FORMAT_IEEE_FLOAT)
153- {
154- bits_pair b ={sample_bits[bits].bits_per_sample,sample_bits[bits].bits_per_sample};
155- make_wave_format(f,sample_rates[rate],channel,b,WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
156- } else {
157- make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_PCM);
158- }
159-
160- // 排他モード
161- HRESULT hr = c->IsFormatSupported(
162- AUDCLNT_SHAREMODE_EXCLUSIVE,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a));
163- if(hr == S_OK){
164- output_device_infos_[d].support_formats[AUDCLNT_SHAREMODE_EXCLUSIVE][ sample_bits[bits].bits_per_sample ][sample_bits[bits].valid_bits_per_sample][channel][sample_rates[rate]] = 0;
165-#ifdef _DEBUG
166- wdout << wformat(L"|exc |bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|") % sample_bits[bits].bits_per_sample % sample_bits[bits].valid_bits_per_sample % channel % sample_rates[rate] % (hr == S_OK?L"OK":L"NG") << endl;
167-#endif }
168-
169- // make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE);
170- // 共有モード
171- hr = c->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a1));
172- if(hr == S_OK){
173- output_device_infos_[d]
174- .support_formats
175- [AUDCLNT_SHAREMODE_SHARED]
176- [ sample_bits[bits].bits_per_sample ]
177- [sample_bits[bits].valid_bits_per_sample]
178- [channel][sample_rates[rate]]
179- = 0;
180-#ifdef _DEBUG
181- wdout << wformat(L"|share|bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|")
182- % sample_bits[bits].bits_per_sample
183- % sample_bits[bits].valid_bits_per_sample
184- % channel % sample_rates[rate]
185- % (hr == S_OK?L"OK":L"NG") << endl;
186454
187-#endif
188- }
189- }
190- }
191- }
455+ }
456+
457+ wasapi_device_manager::device_info::~device_info()
458+ {
459+ try {
460+ boost::filesystem::wpath
461+ config_path(wasapi_device_manager::base_directory() + L"\\" + id_ + L".xml");
462+ boost::filesystem::wofstream ofile(config_path,std::ios_base::out | ios_base::trunc);
463+ boost::archive::xml_woarchive ar(ofile);
464+ ar << BOOST_SERIALIZATION_NVP(params);
465+ } catch(...)
466+ {
467+
468+ }
469+ }
470+
471+ void wasapi_device_manager::output_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo)
472+ {
473+ std::vector<device_info> * infos = nullptr;
192474 #ifdef _DEBUG
193- wdout << "-------------------------------" << std::endl;
475+// if(deviceInfo->IsEnabled){
476+ wdout << deviceInfo->Name->Data() << std::endl;
477+
478+// auto i = deviceInfo->Properties->First();
479+// while(i->HasCurrent)
480+// {
481+//// wdout << iCurrent->Key->Data() << L"," << i->Current->Value->ToString()->Data() << std::endl;
482+// wdout << i->
483+// i->MoveNext();
484+// }
485+// }
194486 #endif
195- }
196- safe_release(c);
197- }
198-
199- // 入力エンドポイントの取得
200- input_device_index_ = get_device_infos(eCapture,input_device_infos_,input_id);
201- // 出力エンドポイントの能力を調査する
202- for(int d = 0;d < input_device_infos_.size();++d)
203- {
204- IAudioClientPtr c;
205- // オーディオクライアントを取得
206- THROW_IF_ERR(
207- input_device_infos_[d].device_ptr
208- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
209- NULL, reinterpret_cast<void **>(&c))
210- );
211-
212- c->GetDevicePeriod(&(input_device_infos_[d].latency_default),&(input_device_infos_[d].latency_minimum));
213- if(input_device_infos_[d].params.latency == 0 || input_device_infos_[d].params.latency < input_device_infos_[d].latency_minimum ){
214- input_device_infos_[d].params.latency = input_device_infos_[d].latency_default;
215- }
487+ }
216488
217-#ifdef _DEBUG
218- wdout << input_device_infos_[d].device_friendly_name << endl;
219- wdout << wformat(L"latency default:%d min:%d") % input_device_infos_[d].latency_default % input_device_infos_[d].latency_minimum << endl;
220-#endif
221- for(int bits = 0;bits < NUM_SAMPLE_BITS;++bits)
222- {
223- for(int channel = 1;channel < 3;++channel)
224- {
225- for(int rate = 0;rate < NUM_SAMPLE_RATE;++rate)
226- {
227- sf::co_task_memory<WAVEFORMATEXTENSIBLE> a,a1;
228- WAVEFORMATEXTENSIBLE f;
229-
230- // make_wave_fomat(f,sample_rates[rate],channel,sample_bits[bits]);
231- if(sample_bits[bits].valid_bits_per_sample == WAVE_FORMAT_IEEE_FLOAT)
232- {
233- bits_pair b ={sample_bits[bits].bits_per_sample,sample_bits[bits].bits_per_sample};
234- make_wave_format(f,sample_rates[rate],channel,b,WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
235- } else {
236- make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_PCM);
237- }
238-
239- // 排他モード
240- HRESULT hr = c->IsFormatSupported(
241- AUDCLNT_SHAREMODE_EXCLUSIVE,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a));
242- if(hr == S_OK){
243- input_device_infos_[d]
244- .support_formats
245- [AUDCLNT_SHAREMODE_EXCLUSIVE]
246- [ sample_bits[bits].bits_per_sample ]
247- [sample_bits[bits].valid_bits_per_sample]
248- [channel]
249- [sample_rates[rate]] = 0;
250-#ifdef _DEBUG
251- wdout << wformat(L"|exc |bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|")
252- % sample_bits[bits].bits_per_sample
253- % sample_bits[bits].valid_bits_per_sample
254- % channel % sample_rates[rate]
255- % (hr == S_OK?L"OK":L"NG") << endl;
256-#endif }
257-
258- // make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE);
259- // 共有モード
260- hr = c->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a1));
261- if(hr == S_OK){
262- input_device_infos_[d].
263- support_formats
264- [AUDCLNT_SHAREMODE_SHARED]
265- [sample_bits[bits].bits_per_sample ]
266- [sample_bits[bits].valid_bits_per_sample]
267- [channel]
268- [sample_rates[rate]] = 0;
269-#ifdef _DEBUG
270- wdout << wformat(L"|share|bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|")
271- % sample_bits[bits].bits_per_sample
272- % sample_bits[bits].valid_bits_per_sample
273- % channel
274- % sample_rates[rate]
275- % (hr == S_OK?L"OK":L"NG") << endl;
489+ void wasapi_device_manager::output_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj)
490+ {
491+ }
276492
277-#endif
278- }
279- }
280- }
281- }
282-#ifdef _DEBUG
283- wdout << "-------------------------------" << std::endl;
284-#endif
285- }
286- safe_release(c);
287- }
288-}//
289-
290- int wasapi_device_manager::get_device_infos(EDataFlow data_flow, std::vector<device_info>& infos,const std::wstring& idd)
291- {
292- // コレクションを取得
293- IMMDeviceCollectionPtr collection;
294- device_enumerator_->EnumAudioEndpoints(data_flow,DEVICE_STATE_ACTIVE ,&collection);
295- uint32_t count;
296- wstring idd_w(idd);
297- // デフォルトデバイスの情報
298- IMMDevicePtr default_device;
299- int default_index = 0;
300- device_enumerator_->GetDefaultAudioEndpoint(data_flow,eMultimedia,&default_device);
301- co_task_memory<WCHAR> iddw;
302- default_device->GetId(&iddw);
303- wstring id_default(iddw.get());
304-
305- if(idd_w.empty() || id_default.size() != idd_w.size())
306- {
307- idd_w.assign(iddw.get());
308- }
309-
310- // 各デバイスの情報を収集する
311- collection->GetCount(&count);
312- bool found = false;
313- for(int i = 0;i < count ;++i)
314- {
315- IMMDevicePtr d;
316- IPropertyStorePtr p;
317- co_task_memory<WCHAR> id;
318- collection->Item(i,&d);
319- d->GetId(&id);
320- d->OpenPropertyStore(STGM_READ,&p);
321- prop_variant difn,ddd,dfn;
322- THROW_IF_ERR(p->GetValue(PKEY_DeviceInterface_FriendlyName, &difn));
323- THROW_IF_ERR(p->GetValue(PKEY_Device_DeviceDesc, &ddd));
324- THROW_IF_ERR(p->GetValue(PKEY_Device_FriendlyName, &difn));
325- infos.push_back(device_info(std::wstring(id.get()),std::wstring(difn.get()->pwszVal),std::wstring(ddd.get()->pwszVal),std::wstring(difn.get()->pwszVal),d));
326-
327- if(infos[i].id == idd_w)
328- {
329- default_index = i;
330- infos[i].is_selected = true;
331- found = true;
332- }
493+ void wasapi_device_manager::output_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)
494+ {
495+ }
333496
497+ void wasapi_device_manager::output_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)
498+ {
499+ }
500+
501+ void wasapi_device_manager::output_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj)
502+ {
503+ }
504+
505+ void wasapi_device_manager::input_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo)
506+ {
507+ std::vector<device_info> * infos = nullptr;
334508 #ifdef _DEBUG
335- wdout << L"--------------------------------------------" << std::endl;
336- wdout << infos[i].device_description << std::endl;
337- wdout << infos[i].device_friendly_name << std::endl;
338- wdout << infos[i].device_interface_friendly_name << std::endl;
339- wdout << infos[i].is_selected << std::endl;
340- wdout << infos[i].id << std::endl;
341-#endif
342- safe_release(p);
343- safe_release(d);
344- }
345-
346- if(!found)
347- {
348- for(int i = 0;i < infos.size();++i)
349- {
350- if(infos[i].id == id_default)
351- {
352- default_index = i;
353- infos[i].is_selected = true;
354- }
355-
356-
357- }
358- }
359- return default_index;
360- }
361-
362- wasapi_device_manager::~wasapi_device_manager()
363- {
364- //for(int i = 0; i <
365- //safe_release(device_collection_);
366- //safe_release(device_collection_);
367- safe_release(device_enumerator_);
368-
369- // 設定の保存
370- try{
371- wstring p = application::instance()->base_directory() + L"\\wasapi_device_manager.config.xml";
372- filesystem::wpath config_path(p);
373- filesystem::wofstream f(config_path,std::ios_base::out | std::ios_base::trunc);
374- archive::xml_woarchive ar(f);
375- ar & boost::serialization::make_nvp("output_device_id",current_output_device().id);
376- ar & boost::serialization::make_nvp("input_device_id" ,current_input_device().id);
377- }catch(...) {
378-
379- }
380- }
381-
382- wasapi_device_manager::device_info::device_info(std::wstring& i,std::wstring& difn,std::wstring& dd,std::wstring& dfn,IMMDevicePtr p)
383- : id(i),device_interface_friendly_name(difn),device_description(dd),device_friendly_name(dfn),is_selected(false)
384- {
385- device_ptr = p;
386- filesystem::wpath config_path(application::instance()->base_directory() + L"\\" + id + L".xml");
387- if(filesystem::exists(config_path))
388- {
389- try{
390- filesystem::wifstream ifile(config_path);
391- boost::archive::xml_wiarchive ar(ifile);
392- ar >> BOOST_SERIALIZATION_NVP(params);
393- } catch (...)
394- {
395- // ファイル読み込みに問題がある場合はファイルを消す。
396- filesystem::remove(config_path);
397- }
398- }
399-#ifdef _DEBUG
400- wdout << L"================================================" << std::endl;
401- wdout << id << L"\n" << device_interface_friendly_name << std::endl;
402- wdout << params.latency << std::endl;
403- wdout << L"================================================" << std::endl;
509+// if(deviceInfo->IsEnabled){
510+ wdout << deviceInfo->Name->Data() << std::endl;
511+
512+// auto i = deviceInfo->Properties->First();
513+// while(i->HasCurrent)
514+// {
515+//// wdout << iCurrent->Key->Data() << L"," << i->Current->Value->ToString()->Data() << std::endl;
516+// wdout << i->
517+// i->MoveNext();
518+// }
519+// }
404520 #endif
521+ }
405522
406- }
407-
408- wasapi_device_manager::device_info::~device_info()
409- {
410- try {
411- filesystem::wpath config_path(application::instance()->base_directory() + L"\\"+ id + L".xml");
412- filesystem::wofstream ofile(config_path,std::ios_base::out | ios_base::trunc);
413- archive::xml_woarchive ar(ofile);
414- ar << BOOST_SERIALIZATION_NVP(params);
415- } catch(...)
416- {
523+ void wasapi_device_manager::input_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj)
524+ {
525+ }
417526
418- }
419- }
527+ void wasapi_device_manager::input_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)
528+ {
529+ }
420530
531+ void wasapi_device_manager::input_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)
532+ {
533+ }
421534
535+ void wasapi_device_manager::input_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj)
536+ {
537+ }
422538 }
\ No newline at end of file
Show on old repository browser