wasapiを実験するプロジェクトです。
Revision | 011ed27321a656dad22a365eacc9ee2f6709fbe1 (tree) |
---|---|
Time | 2012-10-30 04:24:23 |
Author | sfpg <sfpg@user...> |
Commiter | sfpg |
@@ -11,4 +11,5 @@ unix/ | ||
11 | 11 | Debug/ |
12 | 12 | Release/ |
13 | 13 | ipch/ |
14 | -sidplay2/ | |
\ No newline at end of file | ||
14 | +sidplay2/ | |
15 | +backup/ | |
\ No newline at end of file |
@@ -58,7 +58,7 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; | ||
58 | 58 | namespace sf |
59 | 59 | { |
60 | 60 | 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) | |
62 | 62 | ,update_config_dialog_(false) |
63 | 63 | ,edit_output_config_(false) |
64 | 64 | ,edit_input_config_(false) |
@@ -359,7 +359,7 @@ namespace sf | ||
359 | 359 | |
360 | 360 | for(int c = 0;c < i.size();++c) |
361 | 361 | { |
362 | - if(i[c].is_selected){ | |
362 | + if(i[c].is_selected_){ | |
363 | 363 | current_output_driver_index_ = c; |
364 | 364 | } |
365 | 365 | } |
@@ -371,10 +371,13 @@ namespace sf | ||
371 | 371 | wasapi_device_manager::device_infos_t& i(m->input_device_infos()); |
372 | 372 | for(int c = 0;c < i.size();++c) |
373 | 373 | { |
374 | - if(i[c].is_selected){ | |
374 | + if(i[c].is_selected_){ | |
375 | 375 | current_input_driver_index_ = c; |
376 | 376 | } |
377 | 377 | } |
378 | +// if(!i.empty() || current_input_driver_index_ == -1) | |
379 | +// { | |
380 | +// } | |
378 | 381 | } |
379 | 382 | edit_output_config_ = false; |
380 | 383 | edit_input_config_ = false; |
@@ -407,7 +410,7 @@ namespace sf | ||
407 | 410 | |
408 | 411 | for(int c = 0,e = i.size(); c < e;++c) |
409 | 412 | { |
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()); | |
411 | 414 | SendMessage(hwnd_endp,CB_SETITEMDATA,c,c); |
412 | 415 | if(c == current_output_driver_index_) |
413 | 416 | { |
@@ -416,7 +419,7 @@ namespace sf | ||
416 | 419 | } |
417 | 420 | |
418 | 421 | 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_; | |
420 | 423 | //// |
421 | 424 | HWND hwnd_smp_bits = GetDlgItem(hwnd_,IDC_SAMPLE_BIT); |
422 | 425 |
@@ -526,8 +529,8 @@ namespace sf | ||
526 | 529 | // ---------------------------------------- |
527 | 530 | SetDlgItemInt(hwnd_,IDC_LATENCY,editing_output_params_.latency/10000,TRUE); |
528 | 531 | 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()); | |
531 | 534 | } // 出力ダイアログ |
532 | 535 | |
533 | 536 | // =================================================================== |
@@ -541,7 +544,7 @@ namespace sf | ||
541 | 544 | |
542 | 545 | for(int c = 0,e = i.size(); c < e;++c) |
543 | 546 | { |
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()); | |
545 | 548 | SendMessage(hwnd_endp,CB_SETITEMDATA,c,c); |
546 | 549 | if(c == current_input_driver_index_) |
547 | 550 | { |
@@ -550,7 +553,7 @@ namespace sf | ||
550 | 553 | } |
551 | 554 | |
552 | 555 | 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_; | |
554 | 557 | //// |
555 | 558 | HWND hwnd_smp_bits = GetDlgItem(hwnd_,IDC_INPUT_SAMPLE_BIT); |
556 | 559 |
@@ -660,8 +663,8 @@ namespace sf | ||
660 | 663 | // ---------------------------------------- |
661 | 664 | SetDlgItemInt(hwnd_,IDC_INPUT_LATENCY,editing_input_params_.latency/10000,TRUE); |
662 | 665 | 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()); | |
665 | 668 | } // 入力ダイアログ |
666 | 669 | |
667 | 670 | update_config_dialog_ = false; |
@@ -126,11 +126,11 @@ namespace sf { | ||
126 | 126 | ); |
127 | 127 | |
128 | 128 | ID2D1DCRenderTargetPtr dcr; |
129 | - throw_if_err<>()(factory->CreateDCRenderTarget(&props,&dcr)); | |
129 | + throw_if_err<>()(factory->CreateDCRenderTarget(&props,dcr.GetAddressOf())); | |
130 | 130 | RECT rect = {0,0,size.width,size.height}; |
131 | 131 | // 互換DCへのバインド |
132 | 132 | throw_if_err<>()(dcr->BindDC(cdc.get(),&rect)); |
133 | - dcr->DrawBitmap(ptr); | |
133 | + dcr->DrawBitmap(ptr.Get()); | |
134 | 134 | } |
135 | 135 | } |
136 | 136 | icon(bmp,size.width,size.height); |
@@ -119,7 +119,7 @@ namespace sf | ||
119 | 119 | THROW_IFERR(D2D1CreateFactory( |
120 | 120 | D2D1_FACTORY_TYPE_SINGLE_THREADED, |
121 | 121 | options, |
122 | - &factory_ | |
122 | + factory_.GetAddressOf() | |
123 | 123 | )); |
124 | 124 | #else |
125 | 125 | THROW_IFERR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory_)); |
@@ -131,7 +131,7 @@ namespace sf | ||
131 | 131 | THROW_IFERR(::DWriteCreateFactory( |
132 | 132 | DWRITE_FACTORY_TYPE_SHARED, |
133 | 133 | __uuidof(IDWriteFactory), |
134 | - reinterpret_cast<IUnknown**>(&write_factory_) | |
134 | + reinterpret_cast<IUnknown**>(write_factory_.GetAddressOf()) | |
135 | 135 | )); |
136 | 136 | } |
137 | 137 |
@@ -227,9 +227,9 @@ namespace sf | ||
227 | 227 | render_target_->DrawTextW( |
228 | 228 | m.c_str(), |
229 | 229 | m.size(), |
230 | - write_text_format_, | |
230 | + write_text_format_.Get(), | |
231 | 231 | layout_rect_, |
232 | - brush); | |
232 | + brush.Get()); | |
233 | 233 | // render_target_->PopAxisAlignedClip(); |
234 | 234 | THROW_IFERR(render_target_->EndDraw()); |
235 | 235 |
@@ -126,7 +126,7 @@ namespace sf | ||
126 | 126 | THROW_IFERR(D2D1CreateFactory( |
127 | 127 | D2D1_FACTORY_TYPE_SINGLE_THREADED, |
128 | 128 | options, |
129 | - &factory_ | |
129 | + factory_.GetAddressOf() | |
130 | 130 | )); |
131 | 131 | #else |
132 | 132 | THROW_IFERR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory_)); |
@@ -138,7 +138,7 @@ namespace sf | ||
138 | 138 | THROW_IFERR(::DWriteCreateFactory( |
139 | 139 | DWRITE_FACTORY_TYPE_SHARED, |
140 | 140 | __uuidof(IDWriteFactory), |
141 | - reinterpret_cast<IUnknown**>(&write_factory_) | |
141 | + reinterpret_cast<IUnknown**>(write_factory_.GetAddressOf()) | |
142 | 142 | )); |
143 | 143 | } |
144 | 144 |
@@ -236,9 +236,9 @@ namespace sf | ||
236 | 236 | render_target_->DrawTextW( |
237 | 237 | m.c_str(), |
238 | 238 | m.size(), |
239 | - write_text_format_, | |
239 | + write_text_format_.Get(), | |
240 | 240 | layout_rect_, |
241 | - brush); | |
241 | + brush.Get()); | |
242 | 242 | // render_target_->PopAxisAlignedClip(); |
243 | 243 | THROW_IFERR(render_target_->EndDraw()); |
244 | 244 |
@@ -35,7 +35,7 @@ namespace sf | ||
35 | 35 | { |
36 | 36 | if(ptr) |
37 | 37 | { |
38 | - ptr.Release(); | |
38 | + ptr.Reset(); | |
39 | 39 | } |
40 | 40 | }; |
41 | 41 | enum com_init |
@@ -14,7 +14,16 @@ | ||
14 | 14 | #include "sf_windows.h" |
15 | 15 | #include "exception.h" |
16 | 16 | |
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") | |
18 | 27 | |
19 | 28 | #define THROW_IFERR(hres) \ |
20 | 29 | if (FAILED(hres)) { throw sf::win32_error_exception(hres); } |
@@ -24,11 +33,189 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; | ||
24 | 33 | #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) |
25 | 34 | #endif |
26 | 35 | using namespace std; |
36 | +using namespace DirectX; | |
27 | 37 | |
28 | 38 | namespace sf |
29 | 39 | { |
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 | + }; | |
30 | 217 | 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) | |
32 | 219 | { |
33 | 220 | |
34 | 221 | switch (message) |
@@ -54,23 +241,23 @@ namespace sf | ||
54 | 241 | case WM_LBUTTONDOWN: |
55 | 242 | return on_left_mouse_button_down( |
56 | 243 | 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 | + ; | |
59 | 246 | ; |
60 | 247 | case WM_LBUTTONUP: |
61 | 248 | return on_left_mouse_button_up( |
62 | 249 | 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 | + ; | |
65 | 252 | case WM_LBUTTONDBLCLK: |
66 | 253 | return on_left_mouse_button_double_click(wParam, |
67 | 254 | 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 | + ; | |
70 | 257 | case WM_MOUSEMOVE: |
71 | 258 | { |
72 | - return on_mouse_move(wParam, | |
73 | - dpi_.scale_x( | |
259 | + return on_mouse_move(wParam, | |
260 | + dpi_.scale_x( | |
74 | 261 | GET_X_LPARAM(lParam)),dpi_.scale_y(GET_Y_LPARAM(lParam))) |
75 | 262 | ; |
76 | 263 | // on_mouse_move(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam),wParam); |
@@ -78,8 +265,8 @@ namespace sf | ||
78 | 265 | case WM_MOUSEWHEEL: |
79 | 266 | return on_mouse_wheel(GET_KEYSTATE_WPARAM(wParam),GET_WHEEL_DELTA_WPARAM(wParam), |
80 | 267 | 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 | + ; | |
83 | 270 | case WM_MOUSELEAVE: |
84 | 271 | return on_mouse_leave() ; |
85 | 272 | case WM_KEYDOWN: |
@@ -98,14 +285,18 @@ namespace sf | ||
98 | 285 | return on_timer(wParam); |
99 | 286 | case WM_NOTIFY: |
100 | 287 | 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 | |
101 | 292 | } |
102 | 293 | |
103 | 294 | // 他のWindowメッセージを派生クラス側でフックできるようにする |
104 | 295 | return other_window_proc(hwnd,message,wParam,lParam); |
105 | 296 | |
106 | 297 | }; |
107 | - | |
108 | - template <typename ProcType> | |
298 | + | |
299 | + template <typename ProcType> | |
109 | 300 | void base_win32_window<ProcType>::register_class ( |
110 | 301 | const wchar_t * menu_name, |
111 | 302 | uint32_t style , |
@@ -117,18 +308,19 @@ namespace sf | ||
117 | 308 | HICON hIconSm |
118 | 309 | ) |
119 | 310 | { |
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)); | |
121 | 312 | } |
122 | 313 | |
123 | 314 | /** デフォルト設定 */ |
124 | 315 | template <typename ProcType> |
125 | 316 | void base_win32_window<ProcType>::register_class() |
126 | 317 | { |
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)); | |
128 | 320 | } |
129 | 321 | |
130 | 322 | template <typename ProcType> |
131 | - void base_win32_window<ProcType>::create_window() | |
323 | + void base_win32_window<ProcType>::create_window(HWND parent) | |
132 | 324 | { |
133 | 325 | // Create the application window. |
134 | 326 | // |
@@ -139,15 +331,17 @@ namespace sf | ||
139 | 331 | |
140 | 332 | |
141 | 333 | // Windowを作成する |
142 | - CreateWindow( | |
334 | + // Windowを作成する | |
335 | + CreateWindowEx( | |
336 | + WS_EX_APPWINDOW/* | WS_EX_LAYERED */, | |
143 | 337 | name_.c_str(), |
144 | 338 | title_.c_str(), |
145 | - WS_OVERLAPPEDWINDOW, | |
339 | + WS_OVERLAPPEDWINDOW /*| WS_POPUP*/, | |
146 | 340 | CW_USEDEFAULT, |
147 | 341 | 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, | |
151 | 345 | NULL, |
152 | 346 | HINST_THISCOMPONENT, |
153 | 347 | this |
@@ -155,7 +349,7 @@ namespace sf | ||
155 | 349 | ::GetWindowPlacement(hwnd_,&wp_); |
156 | 350 | } |
157 | 351 | |
158 | - | |
352 | + | |
159 | 353 | //void base_win32_window::show() |
160 | 354 | //{ |
161 | 355 | // //HRESULT hr = S_OK; |
@@ -183,21 +377,800 @@ namespace sf | ||
183 | 377 | template <typename ProcType> |
184 | 378 | base_win32_window<ProcType>::~base_win32_window() |
185 | 379 | { |
186 | - | |
187 | 380 | } |
188 | 381 | |
189 | 382 | template <typename ProcType> |
190 | 383 | 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) | |
192 | 385 | { |
386 | + ZeroMemory(&actual_desc_,sizeof(DXGI_MODE_DESC)); | |
387 | + width_ = dpi_.scale_x(width_); | |
388 | + height_ = dpi_.scale_y(height_); | |
193 | 389 | memset(&wp_,0,sizeof(wp_)); |
194 | 390 | wp_.length = sizeof(WINDOWPLACEMENT); |
195 | 391 | 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 | + | |
197 | 1159 | } |
198 | 1160 | |
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>; | |
201 | 1174 | |
202 | 1175 | //ID2D1FactoryPtr base_win32_window::factory() { return impl_->factory();}; |
203 | 1176 | //ID2D1HwndRenderTargetPtr base_win32_window::render_target() { return impl_->render_target();}; |
@@ -205,7 +1178,7 @@ namespace sf | ||
205 | 1178 | |
206 | 1179 | subclass_window::subclass_window(HWND hwnd) |
207 | 1180 | : base_win32_window ( |
208 | - std::wstring(L""),std::wstring(L""),false,0,0 | |
1181 | + std::wstring(L""),std::wstring(L""),false,0,0 | |
209 | 1182 | ),is_subclassed_(false) |
210 | 1183 | { |
211 | 1184 | attach(hwnd); |
@@ -213,7 +1186,7 @@ namespace sf | ||
213 | 1186 | |
214 | 1187 | subclass_window::subclass_window() |
215 | 1188 | : base_win32_window ( |
216 | - std::wstring(L""),std::wstring(L""),false,0,0 | |
1189 | + std::wstring(L""),std::wstring(L""),false,0,0 | |
217 | 1190 | ),is_subclassed_(false) |
218 | 1191 | { |
219 | 1192 |
@@ -2,15 +2,16 @@ | ||
2 | 2 | /* |
3 | 3 | */ |
4 | 4 | // Windows Header Files: |
5 | +#define XBYAK64 | |
5 | 6 | #include "exception.h" |
6 | 7 | #include "base_window.h" |
7 | 8 | #include "dpi.h" |
8 | -#define XBYAK64 | |
9 | 9 | #include "xbyak.h" |
10 | 10 | #include "windows.h" |
11 | 11 | #include "windowsx.h" |
12 | 12 | #include "CommCtrl.h" |
13 | 13 | #include <type_traits> |
14 | +#include "timer.h" | |
14 | 15 | //#include <boost/type_traits/is_same.hpp> |
15 | 16 | // DLLのリンク |
16 | 17 | #pragma comment(lib,"d2d1.lib") |
@@ -20,80 +21,80 @@ | ||
20 | 21 | |
21 | 22 | //#include "input.h" |
22 | 23 | |
24 | + | |
23 | 25 | // Direct Write |
24 | 26 | |
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); | |
36 | 38 | |
37 | 39 | // Direct2D |
38 | 40 | |
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); | |
50 | 52 | |
51 | 53 | // WIC |
52 | 54 | |
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); | |
60 | 62 | |
61 | 63 | // DXGI |
62 | 64 | |
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); | |
74 | 76 | |
75 | 77 | // Direct3D |
76 | 78 | |
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); | |
91 | 92 | |
92 | 93 | namespace sf{ |
93 | 94 | |
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) | |
95 | 96 | { |
96 | - if(hr != S_OK){throw Exc(hr);} | |
97 | + if(hr != S_OK){throw Exc(hr);} | |
97 | 98 | };*/ |
98 | 99 | |
99 | 100 |
@@ -173,6 +174,15 @@ namespace sf{ | ||
173 | 174 | HWND hwnd_; |
174 | 175 | }; |
175 | 176 | |
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 | + | |
176 | 186 | struct compatible_dc { |
177 | 187 | compatible_dc(HDC hdc) : hdc_(::CreateCompatibleDC(hdc)){}; |
178 | 188 | ~compatible_dc(){::DeleteDC(hdc_);}; |
@@ -225,9 +235,9 @@ namespace sf{ | ||
225 | 235 | struct HBITMAP_deleter { |
226 | 236 | typedef HBITMAP pointer; |
227 | 237 | void operator ()(HBITMAP handle) { |
228 | - if (handle) { | |
229 | - ::DeleteObject(handle); | |
230 | - } | |
238 | + if (handle) { | |
239 | + ::DeleteObject(handle); | |
240 | + } | |
231 | 241 | } |
232 | 242 | }; |
233 | 243 |
@@ -259,7 +269,7 @@ namespace sf{ | ||
259 | 269 | |
260 | 270 | // GDI オブジェクト管理テンプレート |
261 | 271 | template <class GdiObject> |
262 | - struct gdi_object: boost::noncopyable | |
272 | + struct gdi_object: boost::noncopyable | |
263 | 273 | { |
264 | 274 | explicit gdi_object(GdiObject obj) : gdiobj_(obj) {} |
265 | 275 | ~gdi_object(){::DeleteObject(gdiobj_);} |
@@ -277,7 +287,7 @@ namespace sf{ | ||
277 | 287 | HDC dc_; |
278 | 288 | HGDIOBJ o_; |
279 | 289 | }; |
280 | - | |
290 | + | |
281 | 291 | // Direct2D BeginDrawヘルパ関数 |
282 | 292 | template <typename T > |
283 | 293 | struct begin_draw |
@@ -286,7 +296,7 @@ namespace sf{ | ||
286 | 296 | |
287 | 297 | begin_draw(T& render_target,err_handler_type& handler) |
288 | 298 | : render_target_(render_target) , |
289 | - is_end_(false),handler_(handler) | |
299 | + is_end_(false),handler_(handler) | |
290 | 300 | {render_target->BeginDraw();} |
291 | 301 | |
292 | 302 | ~begin_draw(){ |
@@ -310,30 +320,41 @@ namespace sf{ | ||
310 | 320 | bool left_button_,middle_button_,right_button_; |
311 | 321 | }; |
312 | 322 | |
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 | |
316 | 326 | { |
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 | + } | |
318 | 333 | }; |
319 | 334 | |
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 | |
323 | 337 | { |
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 | + } | |
325 | 344 | }; |
326 | 345 | |
327 | 346 | /** window ベースクラス */ |
328 | - template <typename ProcType = WNDPROC> | |
347 | + template <typename ProcType = wndproc> | |
329 | 348 | struct base_win32_window : public base_window |
330 | 349 | { |
331 | 350 | typedef ProcType proc_t; |
351 | + typedef typename proc_t::return_type result_t; | |
352 | +// typedef proc_t::return_type result_t; | |
332 | 353 | |
333 | 354 | operator HWND() const {return hwnd_;}; |
334 | - | |
355 | + | |
335 | 356 | virtual void * raw_handle() const {return hwnd_;}; |
336 | -// virtual void show(uint32_t show_flag); | |
357 | + // virtual void show(uint32_t show_flag); | |
337 | 358 | |
338 | 359 | virtual void show() { |
339 | 360 | ::ShowWindow(hwnd_,SW_SHOW); |
@@ -374,17 +395,24 @@ namespace sf{ | ||
374 | 395 | ::MessageBox(hwnd_,text.c_str(),caption.c_str(),type); |
375 | 396 | } |
376 | 397 | |
377 | - | |
378 | 398 | virtual void update(); |
379 | 399 | |
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 | + | |
380 | 408 | protected: |
381 | - | |
409 | + | |
382 | 410 | base_win32_window( |
383 | 411 | const std::wstring& title, |
384 | 412 | const std::wstring& name,bool fit_to_display, |
385 | 413 | float width,float height); |
386 | 414 | |
387 | - | |
415 | + | |
388 | 416 | ~base_win32_window(); |
389 | 417 | |
390 | 418 | void register_class ( |
@@ -400,7 +428,16 @@ namespace sf{ | ||
400 | 428 | |
401 | 429 | /** デフォルト設定 */ |
402 | 430 | 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 | + } | |
404 | 441 | public: |
405 | 442 | // SetWindowLong API |
406 | 443 | void set_long(int index,long data) |
@@ -447,52 +484,87 @@ namespace sf{ | ||
447 | 484 | ::EnableWindow(GetDlgItem(hwnd,id),enable?TRUE:FALSE); |
448 | 485 | }; |
449 | 486 | |
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) | |
452 | 489 | { |
453 | - return def_wnd_proc<ProcType>(hwnd,message,wParam,lParam); | |
490 | + return proc_t::def_wnd_proc(hwnd,message,wParam,lParam); | |
454 | 491 | }; |
455 | - | |
492 | + | |
456 | 493 | // デフォルトウィンドウメッセージハンドラ |
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; } | |
461 | 498 | //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; } | |
472 | 509 | //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) | |
486 | 560 | { |
487 | 561 | 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); | |
491 | 563 | }; |
492 | 564 | |
493 | 565 | // thisとhwndをつなぐthunkクラス |
494 | 566 | 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) | |
496 | 568 | { |
497 | 569 | // rcxにhwndが格納されているので、それをimpl->hwndに保存 |
498 | 570 | // mov(ptr[&(impl->hwnd_)],rcx); // <-- エラー発生部分 |
@@ -507,6 +579,16 @@ namespace sf{ | ||
507 | 579 | } |
508 | 580 | }; |
509 | 581 | |
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 | + | |
510 | 592 | HWND hwnd_; |
511 | 593 | hwnd_this_thunk thunk_; |
512 | 594 | std::wstring title_; |
@@ -514,13 +596,67 @@ namespace sf{ | ||
514 | 596 | float width_,height_; |
515 | 597 | bool fit_to_display_; |
516 | 598 | std::shared_ptr<sf::window_class_ex> wnd_class_; |
517 | - ProcType thunk_proc_; | |
599 | + typename proc_t::proc_type thunk_proc_; | |
518 | 600 | dpi dpi_; |
519 | 601 | 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; | |
524 | 660 | |
525 | 661 | /// サブクラスウィンドウ |
526 | 662 | struct subclass_window : public base_win32_window_t |
@@ -530,7 +666,7 @@ namespace sf{ | ||
530 | 666 | void attach(HWND hwnd); |
531 | 667 | void detatch(); |
532 | 668 | ~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) | |
534 | 670 | { |
535 | 671 | return CallWindowProc(proc_backup_,hwnd,message,wParam,lParam); |
536 | 672 | }; |
@@ -539,33 +675,33 @@ namespace sf{ | ||
539 | 675 | WNDPROC proc_backup_; |
540 | 676 | }; |
541 | 677 | |
542 | -struct av_mm_thread_characteristics | |
543 | -{ | |
544 | - av_mm_thread_characteristics(std::wstring& str) : task_name_(str) | |
678 | + struct av_mm_thread_characteristics | |
545 | 679 | { |
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 | + } | |
548 | 691 | |
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 | + }; | |
550 | 697 | |
551 | - ~av_mm_thread_characteristics() | |
698 | + struct widget | |
552 | 699 | { |
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 | + | |
571 | 707 | } |
\ No newline at end of file |
@@ -104,18 +104,19 @@ | ||
104 | 104 | |
105 | 105 | #include "dxgi.h" |
106 | 106 | |
107 | -// Direct3D | |
108 | - | |
109 | -#include "d3d11.h" | |
107 | +#include "d3d11_1.h" | |
108 | +#include <d3d11shader.h> | |
109 | +#include <DDSTextureLoader.h> | |
110 | 110 | //#include "d3dx11.h" |
111 | 111 | //#include <d3dx11effect.h> |
112 | 112 | //#include <d3dxGlobal.h> |
113 | 113 | #include <d3dcompiler.h> |
114 | -#include <DirectXMath.h> | |
114 | +#include "DirectXMath.h" | |
115 | +//#include <xnamath.h> | |
115 | 116 | |
116 | 117 | // Direct2D |
117 | 118 | |
118 | -#include <d2d1.h> | |
119 | +#include <d2d1_1.h> | |
119 | 120 | #include <d2d1helper.h> |
120 | 121 | |
121 | 122 | // Direct Write |
@@ -141,3 +142,10 @@ | ||
141 | 142 | #include "logger.h" |
142 | 143 | #include "dout.h" |
143 | 144 | //#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 |
@@ -34,7 +34,7 @@ struct taskbar::impl | ||
34 | 34 | } |
35 | 35 | |
36 | 36 | 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())); | |
38 | 38 | } |
39 | 39 | bool is_create() const |
40 | 40 | { |
@@ -69,7 +69,7 @@ struct taskbar::impl | ||
69 | 69 | }; |
70 | 70 | |
71 | 71 | private: |
72 | - _COM_SMARTPTR_TYPEDEF(ITaskbarList4,__uuidof(ITaskbarList4)); | |
72 | + _WRL_PTR_TYPEDEF(ITaskbarList4); | |
73 | 73 | ITaskbarList4Ptr taskbar_; |
74 | 74 | }; |
75 | 75 |
@@ -68,149 +68,149 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; | ||
68 | 68 | namespace sf |
69 | 69 | { |
70 | 70 | |
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"拡大スケーリングを指定します。"); | |
214 | 214 | |
215 | 215 | struct simple_vertex |
216 | 216 | { |
@@ -1019,13 +1019,13 @@ namespace sf | ||
1019 | 1019 | |
1020 | 1020 | THROW_IFERR(wic_factory->CreateBitmapScaler(&scaler)); |
1021 | 1021 | THROW_IFERR(scaler->Initialize( |
1022 | - decoder_source, | |
1022 | + decoder_source.Get(), | |
1023 | 1023 | destination_width, |
1024 | 1024 | destination_height, |
1025 | 1025 | WICBitmapInterpolationModeCubic |
1026 | 1026 | )); |
1027 | 1027 | THROW_IFERR(converter->Initialize( |
1028 | - scaler.GetInterfacePtr(), | |
1028 | + scaler.Get(), | |
1029 | 1029 | GUID_WICPixelFormat32bppPBGRA, |
1030 | 1030 | WICBitmapDitherTypeNone, |
1031 | 1031 | NULL, |
@@ -1036,7 +1036,7 @@ namespace sf | ||
1036 | 1036 | else // Don't scale the image. |
1037 | 1037 | { |
1038 | 1038 | THROW_IFERR(converter->Initialize( |
1039 | - decoder_source.GetInterfacePtr(), | |
1039 | + decoder_source.Get(), | |
1040 | 1040 | GUID_WICPixelFormat32bppPBGRA, |
1041 | 1041 | WICBitmapDitherTypeNone, |
1042 | 1042 | NULL, |
@@ -1047,9 +1047,9 @@ namespace sf | ||
1047 | 1047 | |
1048 | 1048 | // Create a Direct2D bitmap from the WIC bitmap. |
1049 | 1049 | THROW_IFERR(render_target->CreateBitmapFromWicBitmap( |
1050 | - converter.GetInterfacePtr(), | |
1050 | + converter.Get(), | |
1051 | 1051 | NULL, |
1052 | - &bitmap | |
1052 | + bitmap.GetAddressOf() | |
1053 | 1053 | )); |
1054 | 1054 | |
1055 | 1055 | return bitmap; |
@@ -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,¤t_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 | -} |
@@ -34,283 +34,465 @@ Boston, MA 02111-1307 USA | ||
34 | 34 | #define _USE_MATH_DEFINES |
35 | 35 | #include <math.h> |
36 | 36 | #include <limits.h> |
37 | -#pragma comment(lib, "winmm.lib") | |
38 | -#pragma comment(lib, "Avrt.lib") | |
39 | 37 | |
40 | 38 | #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" | |
56 | 41 | |
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; | |
313 | 52 | |
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 | + }; | |
314 | 496 | |
315 | 497 | } |
316 | 498 |
@@ -119,3 +119,5 @@ STRINGTABLE | ||
119 | 119 | // |
120 | 120 | LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN |
121 | 121 | IDI_ICON1 ICON "directx.ico" |
122 | + | |
123 | + |
@@ -42,12 +42,13 @@ | ||
42 | 42 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
43 | 43 | <LinkIncremental>true</LinkIncremental> |
44 | 44 | <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> | |
46 | 47 | </PropertyGroup> |
47 | 48 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
48 | 49 | <LinkIncremental>false</LinkIncremental> |
49 | 50 | <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> | |
51 | 52 | </PropertyGroup> |
52 | 53 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
53 | 54 | <ClCompile> |
@@ -62,6 +63,7 @@ | ||
62 | 63 | <CompileAsWinRT>true</CompileAsWinRT> |
63 | 64 | <AdditionalUsingDirectories>C:\Program Files %28x86%29\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\Microsoft.VCLibs\11.0\References\CommonConfiguration\neutral;%(AdditionalUsingDirectories)</AdditionalUsingDirectories> |
64 | 65 | <MinimalRebuild>false</MinimalRebuild> |
66 | + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> | |
65 | 67 | </ClCompile> |
66 | 68 | <Link> |
67 | 69 | <SubSystem>Windows</SubSystem> |
@@ -20,7 +20,7 @@ Boston, MA 02111-1307 USA | ||
20 | 20 | ============================================================================== |
21 | 21 | */ |
22 | 22 | |
23 | -#include "StdAfx.h" | |
23 | +#include "stdafx.h" | |
24 | 24 | #if _DEBUG |
25 | 25 | #define _CRTDBG_MAP_ALLOC |
26 | 26 | #include <crtdbg.h> |
@@ -28,8 +28,12 @@ Boston, MA 02111-1307 USA | ||
28 | 28 | #endif |
29 | 29 | #include "audio_base.h" |
30 | 30 | #include "wasapi.h" |
31 | +#pragma comment(lib, "winmm.lib") | |
32 | +#pragma comment(lib, "Avrt.lib") | |
33 | +#pragma comment(lib, "Mmdevapi.lib") | |
31 | 34 | |
32 | 35 | using namespace std; |
36 | +using namespace Microsoft::WRL; | |
33 | 37 | |
34 | 38 | namespace sf{ |
35 | 39 |
@@ -42,7 +46,7 @@ namespace sf{ | ||
42 | 46 | wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params) |
43 | 47 | : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_) |
44 | 48 | { |
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); | |
46 | 50 | } |
47 | 51 | |
48 | 52 | // 共有・イベント・再生 |
@@ -50,7 +54,7 @@ namespace sf{ | ||
50 | 54 | wasapi_base<wasapi_shared_policy,wasapi_event_policy,render_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params) |
51 | 55 | : is_enabled_(false),position_(0),is_start_(false),driven_policy_() |
52 | 56 | { |
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); | |
54 | 58 | audio_client_->SetEventHandle(driven_policy_.event_handle()); |
55 | 59 | } |
56 | 60 |
@@ -59,7 +63,7 @@ namespace sf{ | ||
59 | 63 | wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,render_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params) |
60 | 64 | : is_enabled_(false),position_(0),is_start_(false),driven_policy_() |
61 | 65 | { |
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); | |
63 | 67 | audio_client_->SetEventHandle(driven_policy_.event_handle()); |
64 | 68 | } |
65 | 69 |
@@ -68,7 +72,7 @@ namespace sf{ | ||
68 | 72 | wasapi_base<wasapi_shared_policy,wasapi_timer_policy,capture_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params) |
69 | 73 | : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_) |
70 | 74 | { |
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); | |
72 | 76 | } |
73 | 77 | |
74 | 78 | // 排他・タイマ・キャプチャ |
@@ -76,7 +80,7 @@ namespace sf{ | ||
76 | 80 | wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy,capture_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params) |
77 | 81 | : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_) |
78 | 82 | { |
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); | |
80 | 84 | } |
81 | 85 | |
82 | 86 | // 共有・イベント・キャプチャ |
@@ -84,7 +88,7 @@ namespace sf{ | ||
84 | 88 | wasapi_base<wasapi_shared_policy,wasapi_event_policy,capture_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params) |
85 | 89 | : is_enabled_(false),position_(0),is_start_(false),driven_policy_() |
86 | 90 | { |
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); | |
88 | 92 | audio_client_->SetEventHandle(driven_policy_.event_handle()); |
89 | 93 | } |
90 | 94 |
@@ -93,7 +97,7 @@ namespace sf{ | ||
93 | 97 | wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params) |
94 | 98 | : is_enabled_(false),position_(0),is_start_(false),driven_policy_() |
95 | 99 | { |
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); | |
97 | 101 | audio_client_->SetEventHandle(driven_policy_.event_handle()); |
98 | 102 | } |
99 | 103 |
@@ -105,27 +109,35 @@ namespace sf{ | ||
105 | 109 | void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::get_default_audio_client() |
106 | 110 | { |
107 | 111 | |
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 | + } | |
109 | 131 | |
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_); | |
116 | 133 | } |
117 | 134 | |
118 | 135 | template<> |
119 | 136 | void wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy> |
120 | 137 | ::get_default_audio_client() |
121 | 138 | { |
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_); | |
129 | 141 | } |
130 | 142 | |
131 | 143 | // ================================== |
@@ -133,22 +145,34 @@ namespace sf{ | ||
133 | 145 | // ================================== |
134 | 146 | |
135 | 147 | 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) | |
137 | 149 | { |
138 | 150 | WAVEFORMATEXTENSIBLE wfx; |
139 | 151 | bits_pair bits = {params.bits,params.valid_bits}; |
140 | 152 | 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_; | |
142 | 154 | |
143 | 155 | // 代替フォーマット定義 |
144 | 156 | 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; | |
152 | 176 | |
153 | 177 | // 読みこもうとしているWAVファイルのフォーマットをサポートしているか? |
154 | 178 | THROW_IF_ERR(audio_client_->IsFormatSupported( |
@@ -187,11 +211,25 @@ namespace sf{ | ||
187 | 211 | THROW_IF_ERR(audio_client_->GetBufferSize(&buffer_size_)); |
188 | 212 | latency_ = actual_latency_ = |
189 | 213 | (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 | + } | |
195 | 233 | init_audio_client(wfx); |
196 | 234 | |
197 | 235 | } else { |
@@ -318,12 +356,12 @@ namespace sf{ | ||
318 | 356 | { |
319 | 357 | audio_client_->Stop(); |
320 | 358 | audio_client_->Reset(); |
321 | - audio_client_.Release(); | |
359 | + audio_client_.Reset(); | |
322 | 360 | } |
323 | 361 | safe_release(render_client_); |
324 | 362 | safe_release(capture_client_); |
325 | - safe_release(current_device_); | |
326 | - // safe_release(device_enumerator_); | |
363 | + //safe_release(current_device_); | |
364 | + // safe_release(device_collection_); | |
327 | 365 | } |
328 | 366 | |
329 | 367 | // ================================ |
@@ -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,¤t_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 | -} |
@@ -1,26 +1,26 @@ | ||
1 | 1 | /* |
2 | - ============================================================================== | |
2 | +============================================================================== | |
3 | 3 | |
4 | - Copyright 2005-11 by Satoshi Fujiwara. | |
4 | +Copyright 2005-11 by Satoshi Fujiwara. | |
5 | 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. | |
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 | 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. | |
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 | 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 | |
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 | 19 | |
20 | - ============================================================================== | |
20 | +============================================================================== | |
21 | 21 | */ |
22 | 22 | |
23 | -#include "StdAfx.h" | |
23 | +#include "stdafx.h" | |
24 | 24 | #if _DEBUG |
25 | 25 | #define _CRTDBG_MAP_ALLOC |
26 | 26 | #include <crtdbg.h> |
@@ -29,394 +29,510 @@ | ||
29 | 29 | #include "sf_memory.h" |
30 | 30 | #include "audio_base.h" |
31 | 31 | #include "wasapi.h" |
32 | -#include "application.h" | |
33 | -using namespace boost; | |
32 | +//#include "application.h" | |
33 | +//using namespace boost; | |
34 | 34 | 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; | |
137 | 42 | |
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 | + } | |
138 | 448 | #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; | |
141 | 453 | #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; | |
186 | 454 | |
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; | |
192 | 474 | #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 | +// } | |
194 | 486 | #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 | + } | |
216 | 488 | |
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 | + } | |
276 | 492 | |
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 | + } | |
333 | 496 | |
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; | |
334 | 508 | #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 | +// } | |
404 | 520 | #endif |
521 | + } | |
405 | 522 | |
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 | + } | |
417 | 526 | |
418 | - } | |
419 | - } | |
527 | + void wasapi_device_manager::input_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo) | |
528 | + { | |
529 | + } | |
420 | 530 | |
531 | + void wasapi_device_manager::input_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo) | |
532 | + { | |
533 | + } | |
421 | 534 | |
535 | + void wasapi_device_manager::input_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj) | |
536 | + { | |
537 | + } | |
422 | 538 | } |
\ No newline at end of file |