OSDN Git Service

キャプチャ部分のバグ修正。
[winaudioj/wasapi2.git] / wasapi2 / wasapi_base.cpp
1 /*\r
2 ==============================================================================\r
3 \r
4 Copyright 2005-11 by Satoshi Fujiwara.\r
5 \r
6 async can be redistributed and/or modified under the terms of the\r
7 GNU General Public License, as published by the Free Software Foundation;\r
8 either version 2 of the License, or (at your option) any later version.\r
9 \r
10 async is distributed in the hope that it will be useful,\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 GNU General Public License for more details.\r
14 \r
15 You should have received a copy of the GNU General Public License\r
16 along with async; if not, visit www.gnu.org/licenses or write to the\r
17 Free Software Foundation, Inc., 59 Temple Place, Suite 330, \r
18 Boston, MA 02111-1307 USA\r
19 \r
20 ==============================================================================\r
21 */\r
22 \r
23 #include "stdafx.h"\r
24 #if _DEBUG\r
25 #define _CRTDBG_MAP_ALLOC\r
26 #include <crtdbg.h>\r
27 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)\r
28 #endif\r
29 #include "audio_base.h"\r
30 #include "wasapi.h"\r
31 #pragma comment(lib, "winmm.lib")\r
32 #pragma comment(lib, "Avrt.lib")\r
33 #pragma comment(lib, "Mmdevapi.lib")\r
34 \r
35 using namespace std;\r
36 using namespace Microsoft::WRL;\r
37 \r
38 namespace sf{\r
39 \r
40   // ==================================\r
41   // コンストラクタ\r
42   // ==================================\r
43 \r
44   // 共有/排他・タイマー・再生\r
45   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
46   wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::wasapi_base(int device_index,wasapi_device_manager::device_info::params_t& params)\r
47     : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_)\r
48   {\r
49     init(wasapi_device_manager::instance()->output_device_infos().at(device_index),params);\r
50   }\r
51 \r
52   // 共有・イベント・再生\r
53   template<> \r
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)\r
55     : is_enabled_(false),position_(0),is_start_(false),driven_policy_()\r
56   {\r
57     init(wasapi_device_manager::instance()->output_device_infos().at(device_index),params);\r
58     audio_client_->SetEventHandle(driven_policy_.event_handle());\r
59   }\r
60 \r
61   // 排他・イベント・再生\r
62   template<> \r
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)\r
64     : is_enabled_(false),position_(0),is_start_(false),driven_policy_()\r
65   {\r
66     init(wasapi_device_manager::instance()->output_device_infos().at(device_index),params);\r
67     audio_client_->SetEventHandle(driven_policy_.event_handle());\r
68   }\r
69 \r
70   // 共有・タイマ・キャプチャ\r
71   template<> \r
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)\r
73     : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_)\r
74   {\r
75     init(wasapi_device_manager::instance()->input_device_infos().at(device_index),params);\r
76   }\r
77 \r
78   // 排他・タイマ・キャプチャ\r
79   template<> \r
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)\r
81     : is_enabled_(false),position_(0),is_start_(false),driven_policy_(latency_)\r
82   {\r
83     init(wasapi_device_manager::instance()->input_device_infos().at(device_index),params);\r
84   }\r
85 \r
86   // 共有・イベント・キャプチャ\r
87   template<> \r
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)\r
89     : is_enabled_(false),position_(0),is_start_(false),driven_policy_()\r
90   {\r
91     init(wasapi_device_manager::instance()->input_device_infos().at(device_index),params);\r
92     audio_client_->SetEventHandle(driven_policy_.event_handle());\r
93   }\r
94 \r
95   // 排他・イベント・キャプチャ\r
96   template<> \r
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)\r
98     : is_enabled_(false),position_(0),is_start_(false),driven_policy_()\r
99   {\r
100     init(wasapi_device_manager::instance()->input_device_infos().at(device_index),params);\r
101     audio_client_->SetEventHandle(driven_policy_.event_handle());\r
102   }\r
103 \r
104   // ========================================\r
105   // デフォルトのオーディオクライアントの取得\r
106   // ========================================\r
107 \r
108   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
109   void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::get_default_audio_client()\r
110   {\r
111 \r
112     current_device_ = &(wasapi_device_manager::instance()->current_output_device());\r
113       {\r
114         ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;\r
115         IActivateAudioInterfaceAsyncOperation* asyncOp;\r
116         ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());\r
117         HRESULT hr = ActivateAudioInterfaceAsync(current_device_->id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);\r
118         asyncOpPtr.Attach(asyncOp);\r
119         if(SUCCEEDED(hr)){\r
120           handler->wait();\r
121           if(handler->ResultCode() == S_OK)\r
122           {\r
123             audio_client_ = handler->AudioClient();\r
124           } else {\r
125             throw win32_error_exception(handler->ResultCode());\r
126           }\r
127         } else {\r
128           throw win32_error_exception(handler->ResultCode());\r
129         }\r
130       }\r
131 \r
132 //      ActivateAudioInterface(current_device_->id_.c_str(),__uuidof(IAudioClient2),&audio_client_);\r
133   }\r
134 \r
135   template<> \r
136   void wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy>\r
137     ::get_default_audio_client()\r
138   {\r
139     current_device_ = &(wasapi_device_manager::instance()->current_output_device());\r
140 //      ActivateAudioInterface(current_device_->id_.c_str(),__uuidof(IAudioClient2),&audio_client_);\r
141   }\r
142 \r
143   // ==================================\r
144   // 初期化\r
145   // ==================================\r
146 \r
147   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
148   void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::init(wasapi_device_manager::device_info& device,wasapi_device_manager::device_info::params_t& params)\r
149   {\r
150     WAVEFORMATEXTENSIBLE wfx;\r
151     bits_pair bits = {params.bits,params.valid_bits};\r
152     make_wave_format(wfx,params.sample_rate,params.channel,bits);\r
153     latency_ =  params.latency;//wasapi_device_manager::instance()->current_output_device().latency_default_;\r
154 \r
155     // 代替フォーマット定義\r
156     sf::co_task_memory<WAVEFORMATEX>  alt_format;\r
157       {\r
158         ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;\r
159         IActivateAudioInterfaceAsyncOperation* asyncOp;\r
160         ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());\r
161         HRESULT hr = ActivateAudioInterfaceAsync(device.id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);\r
162         asyncOpPtr.Attach(asyncOp);\r
163         if(SUCCEEDED(hr)){\r
164           handler->wait();\r
165           if(handler->ResultCode() == S_OK)\r
166           {\r
167             audio_client_ = handler->AudioClient();\r
168           } else {\r
169             throw win32_error_exception(handler->ResultCode());\r
170           }\r
171         } else {\r
172           throw win32_error_exception(handler->ResultCode());\r
173         }\r
174       }\r
175     current_device_ = &device;\r
176 \r
177     // 読みこもうとしているWAVファイルのフォーマットをサポートしているか?\r
178     THROW_IF_ERR(audio_client_->IsFormatSupported(\r
179       ShareModePolicy::SHARE_MODE ,&wfx.Format,&alt_format));\r
180     //if(hr != S_OK) //  S_FALSEならそのフォーマットをサポートしていないらしい..\r
181     //{\r
182     //  // サンプルレートのコンバート\r
183     //  if(alt_format->nSamplesPerSec != wfx.Format.nSamplesPerSec)\r
184     //  {\r
185     //    // 本来のサンプルレートをバックアップする\r
186     //    sample_rate_backup = wfx.Format.nSamplesPerSec;\r
187     //    // 代替フォーマットのサンプルレートをセットする\r
188     //    wfx.Format.nSamplesPerSec = alt_format->nSamplesPerSec;\r
189     //    // 再計算する\r
190     //    wfx.Format.nAvgBytesPerSec = alt_format->nSamplesPerSec * wfx.Format.nBlockAlign;\r
191     //    // もう一回チェックする。\r
192     //    // サンプルレート以外でサポートしていない点があれば例外が発生する。\r
193     //    THROW_IF_ERR(audio_client_->IsFormatSupported(\r
194     //      ShareModePolicy::SHARE_MODE ,&wfx.Format,&alt_format));\r
195     //    // フラグをセットする\r
196     //    //          sample_rate_convert = true;\r
197     //  } else {\r
198     //    // サンプルレート以外であれば例外を出す。\r
199     //    throw win32_error_exception(hr);\r
200     //  }\r
201     //}\r
202 \r
203     // クライアントの初期化\r
204 \r
205     try {\r
206       init_audio_client(wfx);\r
207     } catch (win32_error_exception& e)\r
208     {\r
209       if(e.hresult() == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED)\r
210       {\r
211         THROW_IF_ERR(audio_client_->GetBufferSize(&buffer_size_));\r
212         latency_ = actual_latency_ = \r
213         (double)10000000 * (buffer_size_) / wfx.Format.nSamplesPerSec;\r
214         audio_client_.Reset();\r
215       {\r
216         ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;\r
217         IActivateAudioInterfaceAsyncOperation* asyncOp;\r
218         ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());\r
219         HRESULT hr = ActivateAudioInterfaceAsync(device.id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);\r
220         asyncOpPtr.Attach(asyncOp);\r
221         if(SUCCEEDED(hr)){\r
222           handler->wait();\r
223           if(handler->ResultCode() == S_OK)\r
224           {\r
225             audio_client_ = handler->AudioClient();\r
226           } else {\r
227             throw win32_error_exception(handler->ResultCode());\r
228           }\r
229         } else {\r
230           throw win32_error_exception(handler->ResultCode());\r
231         }\r
232       }\r
233         init_audio_client(wfx);\r
234 \r
235       } else {\r
236         throw;\r
237       }\r
238     }\r
239     actual_latency_ = latency_;\r
240 \r
241     // バッファサイズの取得\r
242     THROW_IF_ERR(audio_client_->GetBufferSize(&buffer_size_));\r
243 \r
244     init_io_client(boost::type<IOClientPolicy>());\r
245 \r
246     // Audio Clock 2\r
247     THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&audio_clock2_)));\r
248     REFERENCE_TIME psl;\r
249     THROW_IF_ERR(audio_client_->GetStreamLatency(&psl));\r
250 #ifdef _DEBUG\r
251     wdout << L"StreamLatency:" << psl << endl;\r
252 #endif\r
253     //      wdout\r
254 \r
255     // サンプルレートコンバータ\r
256     //if(sample_rate_convert)\r
257     //{\r
258     //  THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&audio_clock_adjustment_)));\r
259     //  // 本来のサンプルレートをセットする\r
260     //  audio_clock_adjustment_->SetSampleRate(sample_rate_backup);\r
261     //}\r
262 \r
263     num_of_frames_ = wfx.Format.nBlockAlign;\r
264     mix_format_ = wfx;\r
265     //inc_  = (buffer_size_ * num_of_frames_) / (sizeof(short) * periods_per_buffer_);\r
266     buffer_in_periods_ = buffer_size_ / periods_per_buffer_;\r
267 \r
268     is_enabled_ = true;\r
269   }\r
270 \r
271   // =========================\r
272   // AudioClientの初期化\r
273   // =========================\r
274   // デフォルト\r
275   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
276   void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::init_audio_client(WAVEFORMATEXTENSIBLE& wfx)\r
277   {\r
278       REFERENCE_TIME buffer_duration =  latency_;\r
279 \r
280       THROW_IF_ERR(audio_client_->Initialize(ShareModePolicy::SHARE_MODE  , \r
281       AUDCLNT_STREAMFLAGS_NOPERSIST | DrivenPolicy::STREAM_FLAG /*| AUDCLNT_STREAMFLAGS_RATEADJUST*/, \r
282       buffer_duration, \r
283       0,\r
284       &(wfx.Format), \r
285       NULL));\r
286   }\r
287 \r
288   // 排他・イベント・出力\r
289   template<> \r
290   void wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,render_client_policy>::init_audio_client(WAVEFORMATEXTENSIBLE& wfx)\r
291   {\r
292     REFERENCE_TIME buffer_duration =  latency_;\r
293 \r
294     THROW_IF_ERR(audio_client_->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE  , \r
295       AUDCLNT_STREAMFLAGS_NOPERSIST | wasapi_event_policy::STREAM_FLAG /*| AUDCLNT_STREAMFLAGS_RATEADJUST*/, \r
296       buffer_duration, \r
297       buffer_duration,\r
298       &(wfx.Format), \r
299       NULL));  \r
300   }\r
301 \r
302   // 排他・タイマー・出力\r
303   template<> \r
304   void wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy,render_client_policy>::init_audio_client(WAVEFORMATEXTENSIBLE& wfx)\r
305   {\r
306     REFERENCE_TIME buffer_period =  latency_;\r
307     REFERENCE_TIME buffer_duration = buffer_period * periods_per_buffer_;\r
308 \r
309     THROW_IF_ERR(audio_client_->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE  , \r
310       AUDCLNT_STREAMFLAGS_NOPERSIST /*| AUDCLNT_STREAMFLAGS_RATEADJUST*/, \r
311       buffer_duration, \r
312       buffer_period,\r
313       &(wfx.Format), \r
314       NULL));  \r
315   }\r
316 \r
317   // 排他・イベント・キャプチャ\r
318   template<> \r
319   void wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy>::init_audio_client(WAVEFORMATEXTENSIBLE& wfx)\r
320   {\r
321     REFERENCE_TIME buffer_duration =  latency_;\r
322 \r
323     THROW_IF_ERR(audio_client_->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE  , \r
324       AUDCLNT_STREAMFLAGS_NOPERSIST | wasapi_event_policy::STREAM_FLAG /*| AUDCLNT_STREAMFLAGS_RATEADJUST*/, \r
325       buffer_duration, \r
326       buffer_duration,\r
327       &(wfx.Format), \r
328       NULL));  \r
329   }\r
330 \r
331   // 排他・タイマー・キャプチャ\r
332   template<> \r
333   void wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy,capture_client_policy>::init_audio_client(WAVEFORMATEXTENSIBLE& wfx)\r
334   {\r
335     REFERENCE_TIME buffer_period =  latency_;\r
336     REFERENCE_TIME buffer_duration = buffer_period * periods_per_buffer_;\r
337 \r
338     THROW_IF_ERR(audio_client_->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE  , \r
339       AUDCLNT_STREAMFLAGS_NOPERSIST /*| AUDCLNT_STREAMFLAGS_RATEADJUST*/, \r
340       buffer_duration, \r
341       buffer_period,\r
342       &(wfx.Format), \r
343       NULL));  \r
344   }\r
345   // ================================\r
346   // デストラクタ\r
347   // ================================\r
348   // デフォルト\r
349   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy>\r
350   wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::~wasapi_base()\r
351   {\r
352     //    safe_release(audio_clock_adjustment_);\r
353 \r
354     // WASAPIの終了処理\r
355     if(audio_client_)\r
356     {\r
357       audio_client_->Stop();\r
358       audio_client_->Reset();\r
359       audio_client_.Reset();\r
360     }\r
361     safe_release(render_client_);\r
362     safe_release(capture_client_);\r
363     //safe_release(current_device_);\r
364     //    safe_release(device_collection_);\r
365   }\r
366 \r
367   // ================================\r
368   // テスト用サイン波形テーブルの作成\r
369   // ================================\r
370   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
371   void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::create_wave_data(){\r
372     // サイン波の生成\r
373     boost::uint32_t buffer_size_in_bytes = buffer_size_ * mix_format_.Format.nBlockAlign;\r
374     size_t render_data_length = mix_format_.Format.nSamplesPerSec * 10 /* 秒 */ * mix_format_.Format.nBlockAlign / sizeof(short);\r
375     tone_buffer_.reserve(render_data_length);\r
376 \r
377     double sampleIncrement = (440 /* Hz */ * (M_PI * 2.0)) / (double)mix_format_.Format.nSamplesPerSec;\r
378     double theta = 0.0;\r
379 \r
380     for (size_t i = 0 ; i < render_data_length ; i += mix_format_.Format.nChannels)\r
381     {\r
382       double sinValue = sin( theta );\r
383       for(size_t j = 0 ;j < mix_format_.Format.nChannels; j++)\r
384       {\r
385         tone_buffer_.push_back((short)(sinValue * _I16_MAX));\r
386       }\r
387       theta += sampleIncrement;\r
388     }\r
389   };\r
390 \r
391   // ===========================\r
392   // バッファを取得する\r
393   // ===========================\r
394   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
395   uint32_t wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::get_buffer(BYTE** buffer,uint32_t size)\r
396   {\r
397 \r
398     uint32_t padding;\r
399     uint32_t frames_available;\r
400 \r
401     THROW_IF_ERR(audio_client_->GetCurrentPadding(&padding));\r
402     frames_available = size - padding;\r
403     THROW_IF_ERR(render_client_->GetBuffer(frames_available,buffer));\r
404     return frames_available;\r
405   }\r
406  \r
407   // 排他・イベント・出力\r
408   template<> \r
409   uint32_t wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,render_client_policy>::get_buffer(BYTE** buffer,uint32_t size)\r
410   {\r
411     THROW_IF_ERR(render_client_->GetBuffer(size,buffer));\r
412     return size;\r
413   }\r
414 \r
415   // キャプチャ ---------------------------------\r
416   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
417   uint32_t wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::get_buffer(BYTE** buffer)\r
418   {\r
419     UINT32 size;\r
420     DWORD flags;\r
421     HRESULT hr = capture_client_->GetBuffer(buffer,&size,&flags,0,0);\r
422     if(hr == AUDCLNT_S_BUFFER_EMPTY)\r
423     {\r
424       buffer = 0;\r
425       size = 0;\r
426     } else {\r
427       THROW_IF_ERR(hr);\r
428     }\r
429 \r
430     if(flags == AUDCLNT_BUFFERFLAGS_SILENT)\r
431     {\r
432       buffer = 0;\r
433       size = 0;\r
434     }\r
435     return size;\r
436   }\r
437 \r
438   // ===========================\r
439   // バッファのリリース\r
440   // ===========================\r
441   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
442   void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::release_buffer(uint32_t  num_byte_written)\r
443   {\r
444     THROW_IF_ERR(render_client_->ReleaseBuffer(num_byte_written,0));\r
445   }\r
446 \r
447   template<> \r
448   void wasapi_base<wasapi_shared_policy,wasapi_event_policy,capture_client_policy>::release_buffer(uint32_t  num_byte_written)\r
449   {\r
450     THROW_IF_ERR(capture_client_->ReleaseBuffer(num_byte_written));\r
451   }\r
452 \r
453   template<> \r
454   void wasapi_base<wasapi_shared_policy,wasapi_timer_policy,capture_client_policy>::release_buffer(uint32_t  num_byte_written)\r
455   {\r
456     THROW_IF_ERR(capture_client_->ReleaseBuffer(num_byte_written));\r
457   }\r
458 \r
459   template<> \r
460   void wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy>::release_buffer(uint32_t  num_byte_written)\r
461   {\r
462     THROW_IF_ERR(capture_client_->ReleaseBuffer(num_byte_written));\r
463   }\r
464 \r
465   template<> \r
466   void wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy,capture_client_policy>::release_buffer(uint32_t  num_byte_written)\r
467   {\r
468     THROW_IF_ERR(capture_client_->ReleaseBuffer(num_byte_written));\r
469   }\r
470 \r
471   // ===========================\r
472   // バッファのスタート\r
473   // ===========================\r
474 \r
475   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
476   void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::start()\r
477   {\r
478     THROW_IF_ERR(audio_client_->Start());\r
479     is_start_ = true;\r
480   }\r
481 \r
482   // ===========================\r
483   // バッファのリセット\r
484   // ===========================\r
485 \r
486   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
487     void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::reset()\r
488   {\r
489     THROW_IF_ERR(audio_client_->Reset());\r
490   }\r
491 \r
492   // ===========================\r
493   // バッファの停止\r
494   // ===========================\r
495 \r
496   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
497   void wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::stop() {\r
498     //再生停止\r
499     if(is_start_)\r
500     {\r
501       THROW_IF_ERR(audio_client_->Stop());\r
502       reset();\r
503       is_start_ = false;\r
504 \r
505     };\r
506   }\r
507 \r
508   // ===========================\r
509   // パディングの取得\r
510   // ===========================\r
511 \r
512   template<typename ShareModePolicy,typename DrivenPolicy,typename IOClientPolicy> \r
513   uint32_t wasapi_base<ShareModePolicy,DrivenPolicy,IOClientPolicy>::get_current_padding()\r
514   {\r
515     uint32_t padding;\r
516     THROW_IF_ERR(audio_client_->GetCurrentPadding(&padding));\r
517     return padding;\r
518   }\r
519 \r
520   template<> \r
521   uint32_t wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,render_client_policy>::get_current_padding()\r
522   {\r
523     return buffer_size_;\r
524   }\r
525 \r
526   template struct wasapi_base<>;\r
527   template struct wasapi_base<wasapi_shared_policy,wasapi_event_policy>;\r
528   template struct wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy>;\r
529   template struct wasapi_base<wasapi_exclusive_policy,wasapi_event_policy>;\r
530   template struct wasapi_base<wasapi_shared_policy,wasapi_timer_policy,capture_client_policy>;\r
531   template struct wasapi_base<wasapi_shared_policy,wasapi_event_policy,capture_client_policy>;\r
532   template struct wasapi_base<wasapi_exclusive_policy,wasapi_timer_policy,capture_client_policy>;\r
533   template struct wasapi_base<wasapi_exclusive_policy,wasapi_event_policy,capture_client_policy>;\r
534 \r
535 }\r
536 \r
537 \r